在EDT中使用OSGi EventAdmin是否安全?

时间:2013-04-19 15:16:55

标签: java swing event-handling osgi

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

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

这样做的目的是让任何订阅者在调用每个订阅者后显示的JPanel上安装所需的内容。

我第一次点击我的按钮,一切都很顺利,因为在EDT中执行了所有操作。 第二次,我的订阅者在不是EDT的线程中调用。因此,我在invokeAndWait启动的runnable中执行JComponent安装。此调用阻塞5022ms(5000ms是默认的EventAdmin超时持续时间)。取消阻止后,会显示我的对话框。 以下时间,我的订户不再被呼叫。它必须已被EventAdmin列入黑名单。

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

2 个答案:

答案 0 :(得分:4)

没有。事件管理员不保证事件将在哪个线程上传递,并且几乎可以肯定不是原始发送线程。

由于您的处理程序不知道它所在的线程,因此无法直接操作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
            }
        });
    }
}

答案 1 :(得分:1)

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