我知道通过使用此方法,runnable参数将提交给系统EventQueue。 但是,如果使用此方法完成所有GUI更新吗?我的意思是,如果我想说,改变一个JButton的文本,我应该使用这样的东西:
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
jButton1.setText("changed text");
}
});
如果我应该使用这种方法,我们可以使用任何模式来避免这种重复的代码?
答案 0 :(得分:26)
当您想要从不是UI线程的另一个线程(事件调度线程)更新UI时,您只需要使用invokeLater
。
假设您有按钮单击的处理程序,并且您希望在有人单击按钮时更改标签的文本。然后直接设置标签文本就完全可以了。这是可能的,因为按钮单击事件的处理程序在UI线程中运行。
但是,假设在另一个按钮上单击启动另一个执行某些工作的线程,在完成此工作后,您需要更新UI。然后使用invokeLater
。此方法可确保在UI线程上执行UI更新。
因此,在很多情况下,您不需要invokeLater
,您可以直接进行UI更新。如果您不确定,可以使用isDispatchThread
检查当前代码是否在事件派发线程内运行。
答案 1 :(得分:2)
只有当您尚未使用事件派发线程时,才需要执行此操作。除非您已经从主线程启动了新线程或执行了代码,否则所有代码可能已经从事件派发线程运行,这使得这不必要。例如,在事件调度线程上调用所有UI事件处理程序,因此您不需要为从那里调用的代码执行此操作。
答案 2 :(得分:1)
您可以使用Eclipse的模板功能,而不是真正避免“重复”(java人可能会说,没有很多秘密的可读代码)。我将它设置为将两个字母“il”扩展到以下块:
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
// do something.
} catch (Exception e) {
e.printStackTrace();
}
}
});
显然这个调度队列设计不仅是推荐的,基本上也是必需的。这可能是我用任何语言将lambda推送到消息队列中的最嘈杂的方式。但它确实如此。这是java。在Java的辩护中,从上面的确切情况来看,它确实显而易见。我不满意打字的数量,但我唯一能想到的就是避免它是C预处理器宏,我打赌Java人不喜欢使用它们。通过模板进行代码扩展更具可读性,可支持性,并且不涉及任何黑魔法。