简体   繁体   English

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

[英]How to access all components beneath top JFrame

Partly for learning purposes, I made a JFrame with 4 JPanel s, 2 JLabel s, and a JMenuBar . 部分出于学习目的,我制作了一个JFrame其中包含4个JPanel ,2个JLabel和一个JMenuBar I put various components (buttons, textboxes, textarea) into the 4 JPanels. 我将各种组件(按钮,文本框,文本区域)放入4个JPanel中。 I disabled every one of the components throughout. 我禁用了所有的每个组件。

I then wrote two methods to try to enable everything. 然后,我编写了两种方法来尝试启用所有功能。 Worked partially. 部分工作。 Here's the code: 这是代码:

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

The JTextArea (inside a JScrollPane ) didn't get enabled even with the last two lines above. 即使上面的最后两行都没有启用JTextArea (在JScrollPane内部)。 Why? 为什么?

I also tried: 我也尝试过:

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

How do I enable the textarea? 如何启用文本区域?

And the JMenuBar didn't get enabled either. 而且JMenuBar也没有启用。 But I really don't know where to find it. 但是我真的不知道在哪里可以找到它。 I read that it's in the JLayeredPane, but ... what I tried with it didn't work: 我读到它在JLayeredPane中,但是...我尝试使用的方法不起作用:

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

In which pane do I find the JMenuBar and how would I enable the JMenu s? 在哪个窗格中可以找到JMenuBar ,如何启用JMenu (And even the JMenuItem s.) (甚至是JMenuItem 。)

Of course, this worked: 当然,这可行:

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

Keep in mind that I'm just experimenting, trying to learn where everything is and how to access it programmatically by drilling down from the top JFrame using something like getComponents() . 请记住,我只是在尝试,试图通过使用诸如getComponents()类的顶级JFrame进行深入研究,来了解所有内容以及如何以编程方式访问它。

1st Edit 第一次编辑

Here's how to get at the menu bar! 这是进入菜单栏的方法!

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

2nd Edit 第二次编辑

See below for recursive partial solution. 请参阅下面的递归部分解决方案。

This is a "recursive response" to @maaartinus (though I only just this second read his note about a stack). 这是对@maaartinus的“递归响应”(尽管我仅此一秒才读过他关于堆栈的注释)。 It's not an answer to my problem, but it's progress. 不是我的问题的答案 ,而是进步。

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

I had to call it twice to get almost everything enabled: 我不得不调用它两次才能启用几乎所有功能:

  gameBoard.enableEverything(gameBoard.getContentPane());
  gameBoard.enableEverything(gameBoard.getJMenuBar());

It did away with one method since it's recursive, and it produced same results in that it also did NOT enable the JMenuItem s or the JTextArea . 它废除了一个方法,因为它是递归的,它产生的,它也没有启用相同的结果JMenuItem S或在JTextArea

So I'm still looking for how to do that. 所以我仍在寻找方法。

It produced interesting output in that every component seems to be an instance of Container, which doesn't seem right: 它产生了有趣的输出,因为每个组件似乎都是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

I was hoping recursion would get at the JMenuItem s, but no such luck. 我希望递归能够到达JMenuItem ,但是没有这种运气。 Any thoughts on how to do so? 关于如何做的任何想法?

I guess you need to recurse the whole tree, something like 我想你需要递归整个树,像

  • start with the root 从根开始
  • iterate all components 迭代所有组件
  • enable each of them 启用每个
  • test if it's an instance of Container 测试它是否是Container的实例
  • if so, do a recursive call 如果是这样,请进行递归调用

For the ScrollPane you'll probably need an additional instanceof test and then getViewPort or something like this. 对于ScrollPane您可能需要一个额外的test instanceof ,然后再getViewPort或类似的内容。

"In which pane do I find the JMenuBar and how would I enable the JMenus? (And even the JMenuItems." “在哪个窗格中可以找到JMenuBar,以及如何启用JMenus?(甚至是JMenuItems。”

The Root Pane of the JFrame holds the JMenuBar . JFrame的根窗格包含JMenuBar

JFrame.getRootPane().getJMenuBar();

Of course you can always just call JFrame.getJMenuBar() , without having to access the root pane. 当然,您始终可以只调用JFrame.getJMenuBar() ,而不必访问根窗格。

To get the menus of the menu bar, you can can JMenuBar.getSubElements which return the MenuElement[] . 要获取菜单栏的菜单,可以通过JMenuBar.getSubElements返回MenuElement[] JMenu Also has getSubElements . JMenu还具有getSubElements Keep in mind though that a MenuELement can be JMenu or a JMenuItem , and a JMenu can have more layers of JMenus. 请记住,尽管MenuELement可以是JMenu JMenuItem ,并且JMenu可以具有更多层JMenus. So you will have to do some recursive calling if you wanted to try to access them this way. 因此,如果您想尝试以这种方式访问​​它们,则必须进行一些递归调用。

As for trying to access specific component types, check if (obj instanceof SomeComponentType) will help you in what you are trying to achieve. 至于尝试访问特定的组件类型,请检查if (obj instanceof SomeComponentType)是否可以帮助您实现目标。

Here's what worked. 这是起作用的。

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

That enables each JMenuItem in JMenu menFileAndEdit in the JMenuBar for the form. 这将为表单启用JMenuBarJMenu menFileAndEdit中的每个JMenuItem

That was a lot harder than expected, given the relative ease with which every other element was enabled by recursion using the method in the second edit of the original post. 考虑到使用原始帖子的第二次编辑中的方法通过递归启用所有其他元素的相对简便性,这比预期的要难得多。 So I wonder if there's a way to use the recursive method to accomplish this. 所以我想知道是否有一种方法可以使用递归方法来完成此任务。

I also wonder if there's a way to use a collection-based for loop. 我也想知道是否有一种方法可以使用基于集合的for循环。 I tried a couple of things but they wouldn't compile. 我尝试了几件事,但它们无法编译。

Six months later, I have a decent, not-altogether-inelegant way to access everything that I needed to below main JFrame, in the context of a menu option action that sets all tool tips to "" : 六个月后,在菜单选项操作(将所有工具提示都设置为""的背景下,我有了一种不错的,并非一成不变的方式来访问我需要在主JFrame下进行的所有操作:

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

Note recursive call to tipsOff . 注意递归调用tipsOff

Also note comments and Answer about using ToolTipManager (in this thread , which works in the context of my original question to reduce all the code to one line. Point here is that any other operation could be applied instead of ""-ing tool tips--eg, setting invisible or disabling... etc. 另请注意有关使用ToolTipManager注释和答案(在此线程中 ,在我最初的问题的上下文中起作用,以将所有代码减少到一行。这里要指出的是,可以应用任何其他操作代替““ -ing工具提示- -例如,设置不可见或禁用...等。

Thanks to maaartinus for the JScrollPane line in tipsOff . 感谢maaartinustipsOffJScrollPane行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM