簡體   English   中英

如何訪問頂部JFrame下的所有組件

[英]How to access all components beneath top JFrame

部分出於學習目的,我制作了一個JFrame其中包含4個JPanel ,2個JLabel和一個JMenuBar 我將各種組件(按鈕,文本框,文本區域)放入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);
}

在哪個窗格中可以找到JMenuBar ,如何啟用JMenu (甚至是JMenuItem 。)

當然,這可行:

menFileAndEdit.setEnabled(true);
mnuFile.setEnabled(true);
mnuEdit.setEnabled(true);
mniFileSave.setEnabled(true);
mniEditUndo.setEnabled(true);
mniEditRedo.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

所以我仍在尋找方法。

它產生了有趣的輸出,因為每個組件似乎都是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 ,但是沒有這種運氣。 關於如何做的任何想法?

我想你需要遞歸整個樹,像

  • 從根開始
  • 迭代所有組件
  • 啟用每個
  • 測試它是否是Container的實例
  • 如果是這樣,請進行遞歸調用

對於ScrollPane您可能需要一個額外的test instanceof ,然后再getViewPort或類似的內容。

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

JFrame的根窗格包含JMenuBar

JFrame.getRootPane().getJMenuBar();

當然,您始終可以只調用JFrame.getJMenuBar() ,而不必訪問根窗格。

要獲取菜單欄的菜單,可以通過JMenuBar.getSubElements返回MenuElement[] JMenu還具有getSubElements 請記住,盡管MenuELement可以是JMenu JMenuItem ,並且JMenu可以具有更多層JMenus. 因此,如果您想嘗試以這種方式訪問​​它們,則必須進行一些遞歸調用。

至於嘗試訪問特定的組件類型,請檢查if (obj instanceof SomeComponentType)是否可以幫助您實現目標。

這是起作用的。

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

這將為表單啟用JMenuBarJMenu menFileAndEdit中的每個JMenuItem

考慮到使用原始帖子的第二次編輯中的方法通過遞歸啟用所有其他元素的相對簡便性,這比預期的要難得多。 所以我想知道是否有一種方法可以使用遞歸方法來完成此任務。

我也想知道是否有一種方法可以使用基於集合的for循環。 我嘗試了幾件事,但它們無法編譯。

六個月后,在菜單選項操作(將所有工具提示都設置為""的背景下,我有了一種不錯的,並非一成不變的方式來訪問我需要在主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);
}     

注意遞歸調用tipsOff

另請注意有關使用ToolTipManager注釋和答案(在此線程中 ,在我最初的問題的上下文中起作用,以將所有代碼減少到一行。這里要指出的是,可以應用任何其他操作代替““ -ing工具提示- -例如,設置不可見或禁用...等。

感謝maaartinustipsOffJScrollPane行。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM