Доступ и создание дерева элементов Swing GUI - PullRequest
0 голосов
/ 29 ноября 2011

Мой вопрос - как получить доступ к дереву элементов Swing GUI (главное окно, JPanels, JFrames, JButtons, JTextFields и т. Д.) И создать ссылку на это дерево.Мне нужно, чтобы это было сохранено в структуре данных (например, хэш-карта), а НЕ в файле памяти (например, с использованием сериализации).Мне нужно это позже, чтобы отобразить эти элементы пользовательского интерфейса в соответствующих объектах внутри кода.

РЕДАКТИРОВАТЬ:

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

    }

Ответы [ 3 ]

3 голосов
/ 29 ноября 2011
2 голосов
/ 29 ноября 2011

Запустите вашу программу из командной строки и введите control + shift + F1 , чтобы увидеть дамп активной иерархии контейнера Swing, как показано здесь . Это не очень хорошо читается, но отступы являются надежным отражением иерархии.

Добавление: полученный таким образом результат полезен в качестве стандарта для оценки программной реализации. Для справки, я запустил Darryl ComponentTree против себя и сравнил результат клавиатуры с копией JTree. Появились только незначительные различия:

  1. Дамп начинается с включенного JFrame, а дерево начинается с корневой панели фрейма.

  2. Дамп имеет лексический отступ, а дерево моделирует иерархию напрямую.

  3. Дамп включает в себя экземпляры CellRendererPane, помеченные hidden , которые используются реализацией рендеринга JTable; дерево нет.

Игнорируя их, порядок компонентов одинаков для обоих.

2 голосов
/ 29 ноября 2011

Я думал об этой проблеме. Вот мое предложение:

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 использует рекурсию, это может вызвать исключение переполнения стека, если в вашем графическом интерфейсе слишком много компонентов.

РЕДАКТИРОВАТЬ Только что проверил этот код на реальном примере и ... он работает:)

Вот код:

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

А вот и вывод:

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...