2011-11-28 64 views
0

我的問題是如何訪問Swing GUI元素樹(主窗口,JPanels,JFrames,JButtons,JTextFields等)並創建對該樹的引用。我需要將它保存在數據結構(如散列圖)中,而不是存儲在文件中(例如使用序列化)。我需要這個以後使用它將這些UI元素映射到代碼中的相應對象。訪問並創建Swing GUI元素的樹

編輯:

JFrame f = new JFrame("Basic GUI"); 
    JPanel pnl1 = new JPanel(); 
    JPanel pnl2 = new JPanel(); 
    JPanel pnl3 = new JPanel(); 

    JLabel lblText = new JLabel("Test Label"); 
    JButton btn1 = new JButton("Button"); 
    JTextField txtField = new JTextField(20); 

    public GUISample(){ 

    pnl1.add(lblText); 
    pnl2.add(btn1); 
    pnl3.add(txtField); 

    f.getContentPane().setLayout(new BorderLayout()); 
    f.getContentPane().add(pnl2, BorderLayout.EAST); 
    f.getContentPane().add(pnl3, BorderLayout.WEST); 
    f.getContentPane().add(pnl1, BorderLayout.NORTH); 
    visitComponent(f); 

    } 

    private Map<String, Component> hashMap = new HashMap<String,Component>(); 

    public Map<String, Component> getComponentsTree(){ 
     return hashMap; 
    } 
    public void visitComponent(Component cmp){ 
     // Add this component 
     if(cmp != null) hashMap.put(cmp.getName(), cmp); 
     Container container = (Container) cmp; 
     if(container == null) { 
      // Not a container, return 
      return; 
     } 
     // Go visit and add all children 
     for(Component subComponent : container.getComponents()){ 
      visitComponent(subComponent); 
     } 
    System.out.println(hashMap); 

    } 
+0

只是爲了確保它很清楚:在給定的Swing應用程序中,您想要在整個組件樹的內存中創建一個數據結構,以及它們的所有父 - >子關係? –

+0

是的,GUI元素樹的整個HIERARCHY被保存在一個數據結構中。 – 100798

+0

您可以使用java.awt.Component.getComponents()來獲取子組件。我們可以看到一個如何使用它的例子嗎?也許有其他選擇? – jeff

回答

2

我一直在思考這個問題。這裏是我的建議:

public class ComponentTreeBuilder{ 
    private Map<String, Component> hashMap = new HashMap<String,Component>(); 
    public Map<String, Component> getComponentsTree(){ 
     return hashMap; 
    } 
    public void visitComponent(Component cmp){ 
     // Add this component 
     if(cmp != null) hashMap.put(cmp.getName(), cmp); 
     Container container = (Container) cmp; 
     if(container == null) { 
      // Not a container, return 
      return; 
     } 
     // Go visit and add all children 
     for(Component subComponent : container.getComponents()){ 
      visitComponent(subComponent); 
     } 
    } 
} 

和使用本這樣的:

Frame myFrame = new JFrame(); 
// Make sure you add your elements into the frame's content pane by 
myFrame.getContentPane(component); 
ComponentTreeBuilder cmpBuilder = new ComponentTreeBuilder(); 
cmpBuilder.visitComponent(myFrame); 
Map<String, Component> components = cmpBuilder.getComponentsTree(); 
// All components should now be in components hashmap 

請注意,ComponentTreeBuilder使用遞歸,如果你在你的GUI組件過多,這可能拋出一個堆棧溢出異常。

編輯只是測試此代碼對真實的例子,並....工程:)

下面是代碼:

JFrame frame = new JFrame(); 
frame.getContentPane().add(new JButton()); 
frame.getContentPane().add(new JButton()); 
frame.getContentPane().add(new JButton()); 
frame.getContentPane().add(new JButton()); 
visitComponent(frame); 

這裏是輸出:

enter image description here

+0

需要小的修正: 在循環「for(Component subComponent :cmp.getComponents()) 它不能識別方法cmp.getComponents。 – 100798

+0

完成,看我的編輯 – GETah

+0

我試過你的解決方案,它的工作原理差不多,唯一的問題是它不顯示整個樹層​​次結構,我檢查了CTRL + SHIFT + F1,你知道爲什麼它不能捕獲整棵樹嗎? – 100798

2

從命令行啓動程序並鍵入控制 + + F1看到活性搖擺容器層次結構的轉儲,如圖here。這不是非常可讀,但縮進是層次結構的可靠反映。

附錄:以這種方式獲得的結果可用作評估程序實現的標準。作爲參考,我對自己運行了Darryl的ComponentTree,並將鍵盤結果與&的粘貼副本JTree進行了比較。只有微小的差異出現了:

  1. 轉儲與封閉JFrame開始,而樹與框架的根窗格開始。

  2. 轉儲在詞彙上是縮進的,而樹則直接對層次建模。

  3. 轉儲包括CellRendererPane實例中,標記爲隱藏,其由JTable渲染實現中使用;樹沒有。

忽略這些,組件順序在兩者中都是相同的。

+0

我認爲PO想要得到這個程序 – GETah

+0

你可能是對的;如果OP不能使用這個,我會發表評論。 – trashgod

+0

是的,我需要這個程序。這與CTRL + SHIFT + F1是很好的,因爲實際上給出了整個樹的層次結構。 @GETah解決方案提供了一些組件,但不是全部,而不是層次結構。任何想法如何管理代碼工作以提供整個層次結構? – 100798