我正在寻找一种简单的方法来使 Swing 组件转发所有收到的内容 事件发送到其父容器(甚至是所有父容器直至root)。
编辑:
我哪里需要这个?我有一个图表编辑器。组件必须转发按键和
鼠标单击(当用户单击子元素时将其自身设置为“Activity ”
该组件)。
首先,让我介绍一下我现有的解决方案。这是一种解决方法。
public interface IUiAction {
void perform(Component c);
}
public static void performRecursiveUiAction(Container parent, IUiAction action) {
if (parent == null) {
return;
}
for (Component c : parent.getComponents()) {
if (c != null) {
action.perform(c);
}
}
for (Component c : parent.getComponents()) {
if (c instanceof Container) {
performRecursiveUiAction((Container) c, action);
}
}
}
/**
* 1) Add listener to container and all existing components (recursively).
* 2) By adding a ContainerListener to container, ensure that all further added
* components will also get the desired listener.
*
* Useful example: Ensure that every component in the whole component
* tree will react on mouse click.
*/
public static void addPermanentListenerRecursively(Container container,
final IUiAction adder) {
final ContainerListener addingListener = new ContainerAdapter() {
@Override
public void componentAdded(ContainerEvent e) {
adder.perform(e.getChild());
}
};
// step 1)
performRecursiveUiAction(container, adder);
// step 2)
performRecursiveUiAction(container, new IUiAction() {
@Override
public void perform(Component c) {
if (c instanceof Container) {
((Container) c).addContainerListener(addingListener);
}
}
});
}
用法:
addPermanentListenerRecursively(someContainer,
new IUiAction(
@Override
public void perform(Component c){
c.addMouseListener(somePermanentMouseListener);
}
)
);
通过查看代码,您认为这是一个好概念吗?
我当前概念的问题是:它仅转发手动指定监听器的事件。
你能推荐一个更好的吗?
最佳答案
根据您的情况,我对键盘方面有一个建议:
您可以使用 swing 的 KeyStroke 工具来实现:
JRootPane rp = getRootPane();
KeyStroke ks = KeyStroke.getKeyStroke(KeyEvent.VK_F2, 0, false);
rp.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(ks, "F2");
rp.getActionMap().put("F2", new AbstractAction() {
public void actionPerformed(ActionEvent e) { onF2Action(); } });
这样您就可以为快捷方式注册“全局”事件处理程序1。
1尽管它可能对您的情况有一些限制。
对于鼠标事件情况,我将创建一个递归函数,它将一个 MouseAdapter
实例添加到每个目标组件。例如:
void addToAll(Container c, MouseAdapter a) {
for (Component p : c.getComponents()) {
if (p instanceof InterrestingComponent) {
p.addMouseListener(a);
p.addMouseMotionListener(a);
p.addMouseWheelListener(a);
} else
if (p instanceof Container) {
addToAll((Container)p, a);
}
}
}
只是为了捕捉这个概念。您可能需要针对不同组件使用不同或多个接收器。
编辑:抱歉,我不小心说的是 WindowAdapter 而不是 MouseAdapter。
关于java - Swing:如何实现子组件的所有事件转发到父容器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1052893/