gpt4 book ai didi

java - 监听后代组件层次结构的变化

转载 作者:太空宇宙 更新时间:2023-11-04 06:34:44 25 4
gpt4 key购买 nike

有没有办法让 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,它将自身添加到添加到“根”容器的容器中(并且,为了完整起见,还会将其自身从已删除的容器中删除,如果这是必要的)。

所以你基本上可以创建一个ContainerListener并将其添加到根容器中。每当此监听器收到有关添加的新子组件的通知时,它也会将自身添加到此组件(如果它是容器)。稍后,当将组件添加到子组件时,监听器将收到通知,并可能再次将其自身添加到孙组件,依此类推。

我在这里举了一个例子:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ContainerEvent;
import java.awt.event.ContainerListener;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class DescendantHierarchyListening extends JPanel
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
createAndShowGUI();
}
});
}

public static void createAndShowGUI()
{
JFrame f = new JFrame();
f.add(new DescendantHierarchyListening());
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(400, 400);
f.setLocationRelativeTo(null);
f.setVisible(true);
}

ContainerListener containerListener = new ContainerListener()
{
@Override
public void componentAdded(ContainerEvent e)
{
Component child = e.getChild();
System.out.println("Added " + child);
System.out.println(" to " + e.getContainer());

if (child instanceof Container)
{
Container container = (Container)child;
container.addContainerListener(this);
}
}

@Override
public void componentRemoved(ContainerEvent e)
{
Component child = e.getChild();
System.out.println("Removed " + child);
System.out.println(" from " + e.getContainer());
if (child instanceof Container)
{
Container container = (Container)child;
container.removeContainerListener(this);
}
}
};

private final JPanel root;
public JPanel leafComponent;

public DescendantHierarchyListening()
{
super(new BorderLayout());

JButton button = createAddChildButton();
add(button, BorderLayout.NORTH);

root = createChildPanel(null);
root.addContainerListener(containerListener);

add(root, BorderLayout.CENTER);
leafComponent = root;
}

private JButton createAddChildButton()
{
JButton button = new JButton("AddChild");
button.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
JPanel child = createChildPanel(leafComponent);
leafComponent.add(child);
leafComponent = child;
revalidate();
}
});
return button;
}

public JPanel createChildPanel(final Container parent)
{
JPanel panel = new JPanel(new BorderLayout())
{
@Override
public String toString()
{
return "Child of " + parent;
}
};
Color color = getColor(parent);
panel.setBorder(BorderFactory.createLineBorder(color, 2));
return panel;
}

private static Color getColor(Component c)
{
if (c == null)
{
return Color.GREEN;
}
Color[] colors = new Color[]
{ Color.RED, Color.BLUE, Color.GREEN };
int d = getDepth(c);
return colors[d % colors.length];
}

private static int getDepth(Component c)
{
if (c == null)
{
return 0;
}
return 1 + getDepth(c.getParent());
}

}

关于java - 监听后代组件层次结构的变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25571162/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com