我的问题是如何访问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<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 :(得分:3)
查看Darryl的Component Tree Model。
答案 1 :(得分: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);
这是输出:
答案 2 :(得分:2)
从命令行启动程序并键入 control + shift + F1 以查看活动Swing容器层次结构的转储,如显示here。它不是非常易读,但是缩进是层次结构的可靠反映。
附录:以这种方式获得的结果可用作评估程序实现的标准。作为参考,我对自己运行了Darryl的ComponentTree
,并将键盘结果与剪切和&amp;粘贴JTree
的副本。只出现了微小的差异:
转储从封闭的JFrame
开始,而树以框架的根窗格开始。
转储是词法缩进的,而树直接为层次结构建模。
转储包含CellRendererPane
的实例,标记为隐藏,由JTable
呈现实现使用;树没有。
忽略这些,组件顺序在两者中都是相同的。