我们是否应该使用EventQueue.invokeLater来处理Java桌面应用程序中的任何GUI更新?

我知道通过使用这个方法,runnable参数被提交给系统EventQueue。 但是,所有的GUI更新都应该使用这种方法来完成? 我的意思是,如果我想说,更改JButton的文本,我应该使用这样的东西:

java.awt.EventQueue.invokeLater(new Runnable() { public void run() { jButton1.setText("changed text"); } }); 

如果我应该使用这种方法,我们可以使用任何模式来避免这个重复的代码?

当你想从另一个不是UI线程的线程(事件调度线程)更新你的UI时,你只需要使用invokeLater

假设你有一个单击button的处理程序,并且当有人单击button时你想要改变标签的文本。 然后直接设置标签文本是完美的保存。 这是可能的,因为button单击事件的处理程序在UI线程中运行。

然而,假设在另一个button上单击,您将启动另一个可以工作的线程,在完成此工作之后,您需要更新UI。 然后你使用invokeLater 。 此方法确保您的UI更新在UI线程上执行。

所以在很多情况下,你不需要invokeLater ,你可以直接做UI更新。 如果不确定,可以使用isDispatchThread来检查当前的代码是否在事件派发线程中运行。

只有当您不在事件派发线程中时才需要执行此操作。 除非你已经从主线程启动了新的线程或者执行了代码,否则所有的代码可能已经从事件调度线程运行,这使得这个不必要。 例如,所有UI事件处理程序都是在事件派发线程上调用的,所以您不需要为从那里调用的代码执行此操作。

而不是真正避免“重复”(Java人可能会说,可读的代码没有很多的秘密),你可以使用Eclipse的模板function。 我已经设置扩展两个字母“il”到以下块:

 EventQueue.invokeLater(new Runnable() { public void run() { try { // do something. } catch (Exception e) { e.printStackTrace(); } } }); 

显然这个派遣队列devise不仅是推荐的,它基本上是必需的。 这可能是我所见过的任何将lambda推入消息队列的语言中最嘈杂的方式。 但是那里呢。 这是java。 而在Java的防守方面,从上面的情况可以清楚地看到发生了什么事情。 我不喜欢打字的数量,但我能想到的唯一的事情就是避免使用C预处理macros,我敢打赌,Java人不喜欢使用这些macros。 通过模板进行代码扩展更具可读性,可支持性,并且不涉及任何黑魔法。