Java 如何访问顶部框架下的所有组件

Java 如何访问顶部框架下的所有组件,java,swing,disabled-control,Java,Swing,Disabled Control,部分出于学习目的,我用4个JPanels、2个JLabels和一个JMenuBar制作了一个JFrame。我将各种组件(按钮、文本框、文本区域)放入4个JPanel中。我在整个过程中禁用了每个组件 然后我编写了两个方法来尝试启用所有功能。部分工作。代码如下: public void enableEverything(){ Component [] p = this.getContentPane().getComponents(); for(Component pp : p)

部分出于学习目的,我用4个
JPanel
s、2个
JLabel
s和一个
JMenuBar
制作了一个
JFrame
。我将各种组件(按钮、文本框、文本区域)放入4个JPanel中。我在整个过程中禁用了每个组件

然后我编写了两个方法来尝试启用所有功能。部分工作。代码如下:

  public void enableEverything(){
    Component [] p = this.getContentPane().getComponents();
    for(Component pp : p)
      if(pp instanceof JPanel)
        enableAll((JPanel) pp);
  }

  public void enableAll(JPanel p){
    Component [] c = p.getComponents();
    for(Component cc: c)
      cc.setEnabled(true);
    jTextArea1.setEnabled(true);
    jScrollPane1.setEnabled(true);
  }
JTextArea
(在
JScrollPane
中)即使在上面的最后两行中也没有启用。为什么?

我还尝试:

Component [] s = jScrollPane1.getComponents();
for(Component ss: s)
  ss.enableInputMethods(true);
如何启用文本区域?

而且
JMenuBar
也没有启用。但我真的不知道在哪里能找到它。我读到它在JLayeredPane中,但是。。。我用它试过的东西不起作用:

for(int i = 0; i < 2; i++){
  System.out.println(i);
  this.getLayeredPane().getComponent(i).setEnabled(true);
}
请记住,我只是在试验,试图通过使用类似于
getComponents()
的工具从顶部向下钻取
JFrame
来了解所有内容的位置以及如何以编程方式访问它

第一次编辑 以下是如何进入菜单栏

Component[] m = this.getJMenuBar().getComponents();
    for(Component mm: m)
      mm.setEnabled(true);
第二版 参见下面的递归部分解决方案

这是对@maaartinus的“递归响应”(尽管我只是在这一秒读了他关于堆栈的注释)。这不是我问题的答案,而是进步

  public void enableEverything(Container c){
    Component [] p = c.getComponents();
    System.out.println("Component count " + c.getComponentCount() + " for " +   
                                            c.toString().substring(0,40)  );
    for(Component pp : p){
        pp.setEnabled(true);
        if(pp instanceof Container){
          System.out.println("Recursive call for " + pp.toString().substring(0,40));
          enableEverything((Container) pp);
        }
        else System.out.println("No recursive call");
    }
我不得不调用它两次,以启用几乎所有功能:

  gameBoard.enableEverything(gameBoard.getContentPane());
  gameBoard.enableEverything(gameBoard.getJMenuBar());
由于它是递归的,所以它取消了一个方法,并产生了相同的结果,即它也没有启用
JMenuItem
s或
JTextArea

所以我仍在寻找如何做到这一点。

它产生了有趣的输出,因为每个组件似乎都是容器的一个实例,这似乎不正确:

 gameBoard.enableEverything(gameBoard.getContentPane())
Component count 6 for javax.swing.JPanel[null.contentPane,0,23
Recursive call for    javax.swing.JPanel[pnlGameGrid,12,139,59
Component count 1 for javax.swing.JPanel[pnlGameGrid,12,139,59
Recursive call for    javax.swing.JTextField[jTextField1,233,1
Component count 0 for javax.swing.JTextField[jTextField1,233,1
Recursive call for    javax.swing.JPanel[pnlAvailableLetters,1
Component count 1 for javax.swing.JPanel[pnlAvailableLetters,1
Recursive call for    javax.swing.JToggleButton[jToggleButton1
Component count 0 for javax.swing.JToggleButton[jToggleButton1
Recursive call for    javax.swing.JLabel[lblAvailableLetters,1
Component count 0 for javax.swing.JLabel[lblAvailableLetters,1
Recursive call for    javax.swing.JPanel[pnlScore,476,25,107x9
Component count 2 for javax.swing.JPanel[pnlScore,476,25,107x9
Recursive call for    javax.swing.JTextField[txtScore,21,14,66
Component count 0 for javax.swing.JTextField[txtScore,21,14,66
Recursive call for    javax.swing.JButton[btnScore,21,61,66x24
Component count 0 for javax.swing.JButton[btnScore,21,61,66x24
Recursive call for    javax.swing.JPanel[pnlPlays,624,51,271x5
Component count 3 for javax.swing.JPanel[pnlPlays,624,51,271x5
Recursive call for    javax.swing.JScrollPane[jScrollPane1,13,
Component count 3 for javax.swing.JScrollPane[jScrollPane1,13,
Recursive call for    javax.swing.JViewport[,1,1,220x80,layout
Component count 1 for javax.swing.JViewport[,1,1,220x80,layout
Recursive call for    javax.swing.JTextArea[jTextArea1,0,0,220
Component count 0 for javax.swing.JTextArea[jTextArea1,0,0,220
Recursive call for    javax.swing.JScrollPane$ScrollBar[,0,0,0
Component count 2 for javax.swing.JScrollPane$ScrollBar[,0,0,0
Recursive call for    javax.swing.plaf.metal.MetalScrollButton
Component count 0 for javax.swing.plaf.metal.MetalScrollButton
Recursive call for    javax.swing.plaf.metal.MetalScrollButton
Component count 0 for javax.swing.plaf.metal.MetalScrollButton
Recursive call for    javax.swing.JScrollPane$ScrollBar[,0,0,0
Component count 2 for javax.swing.JScrollPane$ScrollBar[,0,0,0
Recursive call for    javax.swing.plaf.metal.MetalScrollButton
Component count 0 for javax.swing.plaf.metal.MetalScrollButton
Recursive call for    javax.swing.plaf.metal.MetalScrollButton
Component count 0 for javax.swing.plaf.metal.MetalScrollButton
Recursive call for    javax.swing.JButton[jButton1,61,262,81x2
Component count 0 for javax.swing.JButton[jButton1,61,262,81x2
Recursive call for    javax.swing.JCheckBox[jCheckBox1,49,207,
Component count 0 for javax.swing.JCheckBox[jCheckBox1,49,207,
Recursive call for    javax.swing.JLabel[lblPlays,624,29,100x1
Component count 0 for javax.swing.JLabel[lblPlays,624,29,100x1


gameBoard.enableEverything(gameBoard.getJMenuBar())
Component count 2 for javax.swing.JMenuBar[menFileAndEdit,0,0,
Recursive call for    javax.swing.JMenu[mnuFile,0,0,31x21,alig
Component count 0 for javax.swing.JMenu[mnuFile,0,0,31x21,alig
Recursive call for    javax.swing.JMenu[mnuEdit,31,0,33x21,ali
Component count 0 for javax.swing.JMenu[mnuEdit,31,0,33x21,ali

我原本希望递归能够在
JMenuItem
s上实现,但没有这样的运气有什么想法吗?

我想你需要递归整个树,比如

  • 从根开始
  • 迭代所有组件
  • 启用它们中的每一个
  • 测试它是否是容器的实例
  • 如果是,则执行递归调用

对于
滚动窗格
您可能需要一个额外的
实例
测试,然后
getViewPort
或类似的东西。

我想您需要递归整个树,比如

  • 从根开始
  • 迭代所有组件
  • 启用它们中的每一个
  • 测试它是否是容器的实例
  • 如果是,则执行递归调用

对于
滚动窗格
您可能需要一个额外的
实例
测试,然后
getViewPort
或类似的东西。

我想您需要递归整个树,比如

  • 从根开始
  • 迭代所有组件
  • 启用它们中的每一个
  • 测试它是否是容器的实例
  • 如果是,则执行递归调用

对于
滚动窗格
您可能需要一个额外的
实例
测试,然后
getViewPort
或类似的东西。

我想您需要递归整个树,比如

  • 从根开始
  • 迭代所有组件
  • 启用它们中的每一个
  • 测试它是否是容器的实例
  • 如果是,则执行递归调用
对于
滚动窗格
您可能需要额外的
instanceof
测试,然后是
getViewPort
或类似的内容

“在哪个窗格中可以找到JMenuBar,以及如何启用JMenus?(甚至JMenuItems)。”

JFrame
的根窗格保存
JMenuBar

JFrame.getRootPane().getJMenuBar();
当然,您可以随时调用
JFrame.getJMenuBar()
,而不必访问根窗格

要获取菜单栏的菜单,可以使用
JMenuBar.getSubElements
返回
MenuElement[]
JMenu
也有
getSubElements
。请记住,
menueelement
可以是
JMenu
JMenuItem
,而
JMenu
可以有更多的
JMenus层。
因此,如果您想以这种方式访问它们,就必须执行一些递归调用

至于尝试访问特定的组件类型,请检查
是否(SomeComponentType的obj instanceof)
将帮助您实现您想要实现的目标

“在哪个窗格中可以找到JMenuBar,以及如何启用JMenus?(甚至JMenuItems)。”

JFrame
的根窗格保存
JMenuBar

JFrame.getRootPane().getJMenuBar();
当然,您可以随时调用
JFrame.getJMenuBar()
,而不必访问根窗格

要获取菜单栏的菜单,可以使用
JMenuBar.getSubElements
返回
MenuElement[]
JMenu
也有
getSubElements
。请记住,
menueelement
可以是
JMenu
JMenuItem
,而
JMenu
可以有更多的
JMenus层。
因此,如果您想以这种方式访问它们,就必须执行一些递归调用

至于尝试访问特定的组件类型,请检查
是否(SomeComponentType的obj instanceof)
将帮助您实现您想要实现的目标

“在哪个窗格中可以找到JMenuBar,以及如何启用JMenus?(甚至JMenuItems)。”

JFrame
的根窗格保存
JMenuBar

JFrame.getRootPane().getJMenuBar();
当然,您可以随时调用
JFrame.getJMenuBar()
,而不必访问根窗格

要获取菜单栏的菜单,您可以
JMenuBar。返回
MenuElement[]
JMenu
的getSubElements
也有
getSubElements
。请记住,
MenuElement
可以是
JMenu

private void tipsOff(Container container)
{
  Component [] c = container.getComponents();
  Component s;
  for (Component cc : c) {
    ((JComponent)cc).setToolTipText("");
    if(cc instanceof JPanel)      tipsOff((Container) cc);
    if(cc instanceof JScrollPane) tipsOff(((JScrollPane)cc).getViewport());
  }
}  

private void mniPrefTooltipsActionPerformed(java.awt.event.ActionEvent evt)
{                                                
  tipsOff(gui.getContentPane());
  tipsOff(gui.mbrMenuBar);
}