如何访问顶部JFrame下面的所有组件

时间:2014-04-20 01:22:50

标签: java swing disabled-control

部分出于学习目的,我制作了JFrameJPanel个,2个JLabel个和JMenuBar个。我把各种组件(按钮,文本框,文本区域)放入4个JPanels中。我在整个过程中禁用了所有组件。

然后我写了两个方法来尝试启用所有内容。部分工作。这是代码:

  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);
  }

JTextAreaJScrollPane内)即使上面的最后两行也没有启用。为什么呢?

我也尝试过:

Component [] s = jScrollPane1.getComponents();
for(Component ss: s)
  ss.enableInputMethods(true);

如何启用textarea?

并且JMenuBar也没有启用。但我真的不知道在哪里可以找到它。我读到它在JLayeredPane中,但是...我尝试过它并没有工作:

for(int i = 0; i < 2; i++){
  System.out.println(i);
  this.getLayeredPane().getComponent(i).setEnabled(true);
}

我在哪个窗格中找到JMenuBar以及如何启用JMenu s?(甚至是JMenuItem s。)

当然,这有效:

menFileAndEdit.setEnabled(true);
mnuFile.setEnabled(true);
mnuEdit.setEnabled(true);
mniFileSave.setEnabled(true);
mniEditUndo.setEnabled(true);
mniEditRedo.setEnabled(true);

请注意,我只是尝试,尝试通过使用JFrame之类的内容从顶部getComponents()向下钻取,以编程方式了解所有内容以及如何以编程方式访问它。

第一次编辑

这里是如何进入菜单栏的!

Component[] m = this.getJMenuBar().getComponents();
    for(Component mm: m)
      mm.setEnabled(true);

第二次编辑

请参阅下面的递归部分解决方案。

这是一个&#34;递归响应&#34;到@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());

它取消了一种方法,因为它是递归的,并且它产生了相同的结果,因为它也 NOT 启用JMenuItem s或JTextArea

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

它产生了有趣的输出,因为每个组件似乎都是Container的一个实例,它看起来并不正确:

 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得到,但没有这样的运气。 有关如何操作的任何想法?

4 个答案:

答案 0 :(得分:2)

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

  • 从根
  • 开始
  • 迭代所有组件
  • 启用每个
  • 测试它是否是Container的实例
  • 如果是,请进行递归调用

对于ScrollPane,您可能需要额外的instanceof测试,然后getViewPort或类似的事情。

答案 1 :(得分:1)

  

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

JFrame的根窗格包含JMenuBar

JFrame.getRootPane().getJMenuBar();

当然,您可以随时调用JFrame.getJMenuBar(),而无需访问根窗格。

要获取菜单栏的菜单,您可以JMenuBar.getSubElements返回MenuElement[]JMenu还有getSubElements。请注意,MenuELement可以是JMenu JMenuItem,而JMenu可以有更多JMenus.层如果你想尝试以这种方式访问​​它们,你将不得不做一些递归调用。

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

答案 2 :(得分:0)

这是有效的。

  for(int i = 0; i < menFileAndEdit.getMenuCount(); i++){

      menFileAndEdit.getMenu(i).setEnabled(true);

      Component [] cc = menFileAndEdit.getMenu(i).getMenuComponents();

      for(Component c : cc)

          c.setEnabled(true);
  }

这会为表单JMenuItem中的JMenu menFileAndEdit中的每个JMenuBar启用。

考虑到使用原始帖子的第二次编辑中的方法通过递归启用每个其他元素相对容易,这比预期的要困难得多。所以 我想知道是否有办法使用递归方法来实现这一目标。

我也想知道是否有一种方法可以使用基于集合的for循环。我尝试过几件事,但他们不会编译。

答案 3 :(得分:0)

六个月之后,在菜单选项操作的上下文中,我有一个体面的,非完全不优雅的方式来访问我在主JFrame下面所需的所有内容,该操作将所有工具提示设置为"":< / p>

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);
}     

请注意tipsOff的递归调用。

还要注意有关使用ToolTipManager的评论和答案(在this thread中,它在我的原始问题的上下文中工作,以将所有代码减少到一行。点这里是任何其他操作可能是应用而不是&#34;&#34; - 工具提示 - 例如,设置隐形或禁用...等。

感谢JScrollPanetipsOff行的 maaartinus

相关问题