在Swing环境中可以安全使用EventAdmin吗?我问,因为我有以下顺序:
接收来自JButton的ActionListener通知
创建一个JPanel并将其放在我的事件的属性中
使用EventAdmin#sendEvent(Event)同步发送我的事件
在我的订阅者中接收活动
从属性中检索JPanel,如果不在EDT中,则使用SwingUtilities#InvokeAndWait,将一些JComponent放入其中
在EventAdmin#sendEvent()的调用方中,该方法返回,JPanel已填充,然后可以将其添加到对话框中并显示它。
这样做的目的是让任何订阅者将需要的东西安装到一个JPanel上,一旦每个订阅者被调用,该面板就会显示。
第一次单击按钮时,一切正常,因为在EDT中执行了所有操作。
第二次,在不是EDT的线程中调用我的订户。因此,我在invokeAndWait启动的可运行程序中执行JComponent安装。该调用将阻塞5022ms(5000ms是默认的EventAdmin超时时间)。解除阻止后,将显示我的对话框。
在以下情况下,不再呼叫我的订户。它必须已被EventAdmin列入黑名单。
为什么第二次不在EDT中调用我的订户?
最佳答案
不可以。事件管理员不能保证事件将在哪个线程上传递,并且可以肯定不是原始发送线程。
由于您的处理程序不知道它在哪个线程上,因此它无法直接操作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
}
});
}
}