访问并创建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
的剪切和粘贴副本进行了比较。 只出现了微小的差异:
-
转储从封闭的
JFrame
开始,而树以框架的根窗格开始。 -
转储是词法缩进的,而树直接模拟层次结构。
-
转储包括
CellRendererPane
实例,标记为hidden ,由JTable
呈现实现使用; 树没有。
忽略这些,组件顺序在两者中都是相同的。