SwingUtilities.invokeLater是什么意思?

15
可能重复:

可能重复:
SwingUtilities.invokeLater是什么?
SwingUtilities.invokeLater

我已经看过这段小代码几百次了:

public static void main(String[] args) {
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {
          createAndShowGUI();
        }
    });
}

现在我的问题是:什么是invokeLater()?如果我只在主线程中创建和显示GUI会发生什么样的问题?

4
如你所料,“invokeLater()是做什么的?”在SwingUtilities javadoc页面中得到了回答。 - slim
3个回答

10

1. 事件分派线程 是GUI线程。

2. 如果你在谈论 main() 方法 的话...那么在Java Gui中它不是长时间存在的main() 方法安排好GUI的构建后就会退出,现在是EDT来处理GUI了

3. invokeLater 表示这个调用将会立即返回,因为事件已被放置在事件分派队列中,并且 run() 方法将会异步地运行...


4
好的,我会尽力以通俗易懂的方式翻译内容。请考虑使用技术术语,这样我们都能理解您的真实意图(“不长寿”或“同时运行”不是很清晰或有歧义). - kleopatra

5

Swing不是线程安全的,所有对Swing对象的更改必须在事件分发线程中执行。如果你试图在其他线程中运行代码,将会得到未指定的行为,这可能在某个时刻变得异常奇怪。

相比之下,Eclipse使用的SWT/JFace GUI框架在每个公共入口点上都断言了正确的线程。


4
如果您试图在外部运行代码,由于在执行任何进一步操作之前会检查调用线程,因此只会引发异常。但在事件分派线程(EDT)之外运行UI相关的内容可能会导致奇怪的行为,但不一定会抛出异常。 - assylias
1
不仅是更改操作 - 每一个访问(包括实例化)都必须在EDT上进行。 - kleopatra
那个异常仅在JavaFX中出现,他们最终包含了检查。你可以通过使用自定义重绘管理器,在Swing中实现类似的行为,如此处所解释的。 - Robin
1
@assylias和Robin,感谢你们的纠正。我同时使用Swing和SWT/JFace,把它们搞混了。 - Marko Topolnik

2
如果您遵循指南,从EDT更新它不会发生任何不良情况。
也就是说...

如果从事件分派线程(例如从JButton的ActionListener)调用invokeLater,则doRun.run()仍将被延迟,直到处理完所有未决事件。

来源 如果不是这种情况,则需要使用invokeLater()
它会安排一个Runnable,该Runnable将在EDT(事件分派线程)上执行。

2
大多数情况下,您正在从“线程”中执行所有操作。您是否意味着“不是主线程”? - 11684
6
很抱歉,今天的投票机会已用完,所以我给你的回答打了一个“-1”,意思是“没有什么不好的意思”。请修改你的回答,让人更好地理解你的意思。 - kleopatra
1
那么,如果我把我的代码放在invokeLater()中,那个Runnable将会从EDT执行,并且不会产生任何“奇怪的行为”(如assylias所述)?那么,如果我想要更新我的JLabel的文本,我应该再次正式地将其放在invokeLater()中吗? - 11684
@assylias 我怎么知道呢? - 11684
1
@11684即使您EDT中,invokeLater仍将起作用,因此最好使用它。 - slim
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接