Есть ли способ для JComponent
получить уведомление о добавлении/удалении изменений в иерархии его потомков?Прослушивание изменений иерархии компонентов потомков
Например, в коде ниже есть кнопка addChild
, которая добавит нового ребенка JPanel
к корню или к последней добавленной панели. Я хотел бы, чтобы корневая панель получила уведомление об этом. Похоже на HierarchyListener
, но наоборот, или ContainerListener
, который слушал больше, чем просто детей.
public class DecendantHierarchyListening extends JFrame {
private final JPanel root = createChildPanel(null);
public JPanel leafComponent = root;
public DecendantHierarchyListening() {
super("title");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JComponent buttons = new JPanel();
JPanel panel = new JPanel(new BorderLayout());
panel.add(createAddChildButton(buttons), BorderLayout.NORTH);
panel.add(root, BorderLayout.CENTER);
getContentPane().add(panel);
}
private Button createAddChildButton(JComponent buttons) {
Button button = new Button("AddChild");
buttons.add(button);
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
leafComponent = (JPanel) leafComponent
.add(createChildPanel(leafComponent));
DecendantHierarchyListening.this.invalidate();
DecendantHierarchyListening.this.validate();
DecendantHierarchyListening.this.repaint();
}
});
return button;
}
public static JPanel createChildPanel(Container parent) {
Color[] colors = new Color[] { Color.RED, Color.BLUE, Color.GREEN };
JPanel panel = new JPanel(new BorderLayout());
panel.setPreferredSize(new Dimension(200, 200));
Color color;
if (parent == null) {
color = Color.GREEN;
} else {
int distance = 1;
parent = parent.getParent();
while (parent != null) {
distance++;
parent = parent.getParent();
}
color = colors[distance % colors.length];
}
panel.setBorder(BorderFactory.createLineBorder(color, 2));
return panel;
}
public static void runDemo() {
JFrame f = new DecendantHeirarchyListening();
f.pack();
f.setVisible(true);
}
public static void main(String[] args) {
DecendantHierarchyListening.runDemo();
}
}
Я думаю, что вы можете работать вокруг этого довольно легко. Почему вы даже хотите слушать события, которые не влияют на конкретный компонент? Например, вы можете использовать один контейнер ContainerListener для всех контейнеров, из которых вы хотите получать уведомления. Добавление ребенка к дочернему компоненту компонента технически не влияет на него (если вы не сделаете корректировку для первого ребенка). Это другой подход: используйте компоненты в «середине» иерархии, чтобы уведомлять компоненты верхнего уровня. – J4v4