这个简单的问题让我困惑。 您可以通过设置帧显示JAVA GUI应用程序setVisible
财产true
。 但在几乎所有我互联网上找到的例子,他们使用一个单独的线程做同样的事情。
他们这样做,
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new Frame().setvisible(true); //just take the idea of this line
}
});
我发现这两种方法之间没有什么区别。 但是, 必须有一些特殊的原因,这就是为什么大家都在做这个。
谁能解释it..thanks!
以这种方式启动了应用程序的主要理由是,Swing组件不是线程安全的 ,所以你需要保证哪个线程你的GUI将开始:一个叫Event Dispatching Thread
(EDT)。 如果不这样做,你不能肯定它会开始什么的线程,但通过几种评论家指出,主线程保证不会成为 EDT。
您应该只创建,访问,或者从美国东部时间内修改UI组件。 这样做,否则会导致意外的行为(如果你幸运的话)和/或脏重绘。
一些资源,我建议你熟悉:
你也可以有一个读为什么我的样板Java桌面应用程序的JFrame使用EventQueue.invokeLater的主要方法是什么?
UPDATE
这是博客 ,我一直试图找到:P
基本上,这解释了为什么它同步您的重要main
在开始前与EDT,它也介绍了一些有关为何细节。
这也说明为什么许多开发商开始他们的应用程序时,使这个根本的错误(基本上,我们被告知,我们可以,但我们从来没有真正被允许...坏我们)
因为你在GUI做的每次修改应在上完成事件分派线程 。 这是AWT和SWING的意思是如何工作的。
这是因为重绘在单个线程上执行,使用invokeLater
你让线程管理,而不必因缺乏摆动的线程安全的潜在发行。 使用语法你委派的说明了恰当线程上执行,这是管理GUI元素之一。
Swing是不是线程安全的,需要在被初始化所有组件EDT 。 这将防止问题,如死锁。
Swing的类不是线程安全的; 他们得到他们的线程正确性仅仅从他们的一切行动都在同一个线程(事件指派线程或EDT)上执行的事实。 所以,你有一个Swing对象交互任何时候,都必须在美国东部时间-和SwingUtilities.invokeLater
是做到这一点的好办法。
如果没有这个电话,如果你只是叫setVisible(true)
从任何醇”线程,你不会有任何线程安全和Frame
甚至可能没有看到,法的行为。 更糟糕的是,该Frame
只能看到一些行动,打破内部的假设和不变,造成异常行为,崩溃或死锁。
几乎调用Swing方法进行任何操作必须在Swing事件分派线程上运行。 的invokeLater()是为了确保这个不变的持有方式。 了解更多关于此这里 。
还要注意的是,同样是约其他大多数的GUI工具包,如.NET,MFC和其他形式的真实。
Java的GUI框架被设计为一个单独的线程来执行线程安全:该技术被称为线程约束。 因此,任何GUI操作如组件的创建,模型制作,发送事件等必须执行的事件指派线程(EDT)。 您所描述的方法是排队在EDT操作的一种方式。