访问并创建Swing GUI元素树

我的问题是如何访问Swing GUI元素树(主窗口,JPanels,JFrames,JButtons,JTextFields等)并创建对该树的引用。 我需要将它保存在数据结构(例如散列映射)中,而不是保存在内存文件中(例如,使用序列化)。 我需要这个以后使用它来将这些UI元素映射到代码中的相应对象。

编辑:

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 hashMap = new HashMap(); public Map 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); } 

我一直在想这个问题。 这是我的建议:

 public class ComponentTreeBuilder{ private Map hashMap = new HashMap(); public Map 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 components = cmpBuilder.getComponentsTree(); // All components should now be in components hashmap 

请注意, ComponentTreeBuilder正在使用递归,如果GUI中有太多组件,这可能会引发堆栈溢出exception。

编辑刚刚在真实的例子上测试了这段代码……它的工作原理:)

这是代码:

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

这是输出:

在此处输入图像描述

查看Darryl的组件树模型 。

从命令行启动程序并键入control + shift + F1以查看活动Swing容器层次结构的转储,如此处所示。 它不是非常易读,但缩进是层次结构的可靠反映。

附录:以这种方式获得的结果可用作评估程序实现的标准。 作为参考,我对自己运行了Darryl的ComponentTree ,并将键盘结果与JTree的剪切和粘贴副本进行了比较。 只出现了微小的差异:

  1. 转储从封闭的JFrame开始,而树以框架的根窗格开始。

  2. 转储是词法缩进的,而树直接模拟层次结构。

  3. 转储包括CellRendererPane实例,标记为hidden ,由JTable呈现实现使用; 树没有。

忽略这些,组件顺序在两者中都是相同的。