java - Swing:如何实现子组件的所有事件转发到父容器?

标签 java user-interface swing events

我正在寻找一种简单的方法来使 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/

相关文章:

Java - JToggleButton - 虽然无限循环 - 无法单击按钮两次

java - 在 Docker 上运行 Java Swing GUI 应用程序

java - 是否可以将初始化部分分成不同的类?

java - 如何在 5 秒后更改 jtextfield 边框?

java - 为什么即使在更新了 Grails 中的 Selenium 依赖项后,我的 Geb 测试仍会返回 "failed to create driver from callback"?

java - Servlet 发送旧版本的实体 (JPA)

java - 如何将 servlet contextPath 与 PropertySource 一起使用?

c# - 如何创建一个带有指向另一个窗口的箭头的窗口?

java - Android java.lang.ArrayIndexOutOfBoundsException : length=10; index=10

asp.net-mvc - 使用ASP.NET MVC时,如何有效地使用Visual Studio中的 "Add view"对话框?