100798
100798

Reputation: 231

Access and create a tree of Swing GUI elements

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

Answers (3)

GETah
GETah

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:

enter image description here

Upvotes: 2

trashgod
trashgod

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:

  1. The dump starts with the enclosing JFrame, while the tree starts with the frame's root pane.

  2. The dump is lexically indented, while the tree models the hierarchy directly.

  3. 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

camickr
camickr

Reputation: 324108

Check out Darryl's Component Tree Model.

Upvotes: 3

Related Questions