java.awt.EventQueue.invokeLater解释
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22534356/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
java.awt.EventQueue.invokeLater explained
提问by Quillion
I am very curious why do we have to use java.awt.EventQueue.invokeLater
to control swing components.
我很好奇我们为什么要使用java.awt.EventQueue.invokeLater
来控制swing组件。
Why can't we do that in normal thread? What exactly is going on behind the scenes? From what I have noticed if I have a JFrame
I can set visibility to true or false from the main thread without getting any errors, and it does seem to work. So what exactly do I achieve by using java.awt.EventQueue.invokeLater
? I am also fully aware that I can use SwingUtilities.invokeLater
but as explained here, they seem to be one and the same thing.
为什么我们不能在普通线程中做到这一点?幕后究竟发生了什么?根据我所注意到的,如果我有一个JFrame
我可以在主线程中将可见性设置为 true 或 false 而不会出现任何错误,并且它似乎确实有效。那么我到底能通过使用实现java.awt.EventQueue.invokeLater
什么?我也完全知道我可以使用,SwingUtilities.invokeLater
但正如这里所解释的,它们似乎是一回事。
Thanks to anyone for their explanation. Hopefully this is a valid question.
感谢任何人的解释。希望这是一个有效的问题。
EDIT: to answer wumpz question We can create a jframe
编辑:回答wumpz问题我们可以创建一个jframe
JFrame frame = new JFrame("Hello world");
frame.setSize(new Dimension(300, 300));
frame.setPreferredSize(new Dimension(300, 300));
frame.setMaximumSize(new Dimension(300, 300));
frame.setMinimumSize(new Dimension(300, 300));
frame.setVisible(true);
frame.pack();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
And on the same thread it was created do the following.
在创建它的同一个线程上执行以下操作。
for (int i = 0; i < 34; i++)
{
System.out.println("Main thread setting to "+(!frame.isVisible()));
frame.setVisible(!frame.isVisible());
}
And no complaints.
并且没有抱怨。
采纳答案by wumpz
The complete Swing processing is done in a thread called EDT (Event Dispatching Thread). Therefore you would block the GUI if you would compute some long lasting calculations within this thread.
完整的 Swing 处理是在称为EDT(事件调度线程)的线程中完成的。因此,如果您要在此线程中计算一些持久的计算,则会阻塞 GUI。
The way to go here is to process your calculation within a different thread, so your GUI stays responsive. At the end you want to update your GUI, which have tobe done within the EDT. Now EventQueue.invokeLater
comes into play. It posts an event (your Runnable
) at the end of Swings event list and is processed after all previous GUI events are processed.
去这里的方法是在不同的线程中处理您的计算,以便您的 GUI 保持响应。最后,您想要更新您的 GUI,这必须在 EDT 中完成。现在EventQueue.invokeLater
开始发挥作用。它Runnable
在 Swings 事件列表的末尾发布一个事件 (your ),并在处理完所有先前的 GUI 事件之后进行处理。
Also the usage of EventQueue.invokeAndWait
is possible here. The difference is, that your calculation thread blocks until your GUI is updated.
So it is obvious that this must not be used from the EDT.
EventQueue.invokeAndWait
这里也可以使用。不同之处在于,您的计算线程会阻塞,直到您的 GUI 更新。所以很明显,这不能从 EDT 中使用。
Be careful notto update your Swing GUI from a different thread. In most cases this produces some strange updating/refreshing issues.
注意不要从其他线程更新 Swing GUI。在大多数情况下,这会产生一些奇怪的更新/刷新问题。
Still there is Java code out there that starts a JFrame simple from the main thread. This could cause issues, but is not prevented from Swing. Most modern IDEs now create something like this to start the GUI:
仍然有 Java 代码从主线程启动一个简单的 JFrame。这可能会导致问题,但不会阻止 Swing。大多数现代 IDE 现在创建类似这样的东西来启动 GUI:
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new NewJFrame().setVisible(true);
}
});
}
回答by trashgod
All supported platformsoffer single-threaded graphics libraries. Swing is cross-platform. Therefore, Swing GUI objects should be constructed and manipulated onlyon the event dispatch thread.
所有支持的平台都提供单线程图形库。Swing 是跨平台的。因此,Swing GUI 对象应该只在事件分派线程上构造和操作。
As an aside, SwingUtilities.invokeLater()
is a cover for EventQueue.invokeLater()
since version 1.3.
顺便说SwingUtilities.invokeLater()
一句,是EventQueue.invokeLater()
自 1.3 版以来的封面。