1

EventAdmin 在 Swing 环境中使用是否安全?我问是因为我有以下序列:

  • 从 JButton 接收 ActionListener 通知
  • 创建一个 JPanel 并将其放在我的 Event 的属性中
  • 使用 EventAdmin#sendEvent(Event) 同步发送我的事件
  • 在我的订阅者中接收事件
  • 从属性中检索 JPanel,如果不在 EDT 中,则使用 SwingUtilities#InvokeAndWait,将一些 JComponents 放入其中
  • 在 EventAdmin#sendEvent() 的调用者中,方法返回,JPanel 已被填充,然后我可以将它添加到我的对话框并显示它。

这样做的目的是让任何订阅者将所需的内容安装到 JPanel,一旦每个订阅者被调用,该 JPanel 就会显示。

我第一次单击按钮时,一切正常,因为一切都在 EDT 中执行。第二次,我的订阅者在不是 EDT 的线程中被调用。因此,我在由 invokeAndWait 启动的可运行文件中执行 JComponent 安装。此调用阻塞 5022 毫秒(5000 毫秒是默认的 EventAdmin 超时持续时间)。一旦解锁,我的对话框就会显示出来。接下来的时间,我的订阅者不再被调用。它必须已被 EventAdmin 列入黑名单。

为什么第二次没有在 EDT 中调用我的订阅者?

4

2 回答 2

4

不会。Event Admin 不保证将在哪个线程上传递事件,并且几乎可以肯定不是原始发送线程。

由于您的处理程序不知道它在哪个线程上,因此它不能直接操作 GUI。相反,它必须使用SwingUtilities.invokeLater()将 Runnable 推送到事件队列中,并且在该 Runnable 中您可以进行 GUI 更改。例如:

class MyEventHandler implements EventHandler {
    public void handleEvent(final Event event) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                // here you can make the UI changes in response to the event data
            }
        });
    }
}
于 2013-04-20T07:04:12.530 回答
1

EventAdmin 规范不要求在发布事件的同一线程上传递事件。您需要使用添加此保证的 EventAdmin 实现,因为您必须在发布事件的同一线程上接收事件。

于 2013-04-19T17:16:24.377 回答