Reputation: 231
My question is how to access the Swing GUI element tree (main window, JPanels, JFrames, JButtons, JTextFields ect) and create a reference to that tree. I need this to be kept in a data structure (ex. hash map) and NOT in a memory file (eg. using serialization). I need this for using it later to map these UI elements to the corresponding objects inside the code.
EDIT:
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);
}
Upvotes: 0
Views: 3163
Reputation: 21409
I have been thinking about this problem. Here is my suggestion:
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);
}
}
}
And use this like this:
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
Please note that ComponentTreeBuilder
is using recursion, this might throw a stack overflow exception if you have too many components in your GUI.
EDIT Just tested this code on real example and.... it works :)
Here is the code:
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);
And here is the output:
Upvotes: 2
Reputation: 205785
Start your program from the command line and type control+shift+F1 to see a dump of the active Swing container hierarchy, as shown here. It's not terribly readable, but the indents are a reliable reflection of the hierarchy.
Addendum: The result obtained in this manner is useful as a standard against which to evaluate a programatic implementation. For reference, I ran Darryl's ComponentTree
against itself and compared the keyboard result to a cut & paste copy of the JTree
. Only minor differences emerged:
The dump starts with the enclosing JFrame
, while the tree starts with the frame's root pane.
The dump is lexically indented, while the tree models the hierarchy directly.
The dump includes instances of CellRendererPane
, marked hidden, which are used by the JTable
rendering implementation; the tree does not.
Ignoring these, the component order is identical in both.
Upvotes: 3