java.awt.EventQueue.invokeLater 解释
我很好奇为什么我们必须使用java.awt.EventQueue.invokeLater
来控制swing组件.
I am very curious why do we have to use java.awt.EventQueue.invokeLater
to control swing components.
为什么我们不能在普通线程中这样做?幕后究竟发生了什么?从我注意到的情况来看,如果我有一个 JFrame
我可以从主线程将可见性设置为 true 或 false 而不会出现任何错误,而且它似乎确实有效.那么使用 java.awt.EventQueue.invokeLater
究竟能实现什么?我也完全知道我可以使用 SwingUtilities.invokeLater
但正如 解释在这里,它们似乎是一回事.
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.
感谢任何人的解释.希望这是一个有效的问题.
Thanks to anyone for their explanation. Hopefully this is a valid question.
回答 wumpz 问题我们可以创建一个jframe
to answer wumpz question We can create a 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());
}
没有抱怨.
推荐答案
完整的 Swing 处理在一个名为 EDT(Event Dispatching Thread) 的线程中完成.因此,如果您要在此线程中计算一些持久的计算,您将阻止 GUI.
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.
这里的方法是在不同的线程中处理您的计算,以便您的 GUI 保持响应.最后,您想要更新您的 GUI,这必须在 EDT 内完成.现在 EventQueue.invokeLater
开始发挥作用.它在 Swings 事件列表的末尾发布一个事件(您的 Runnable
),并在处理完所有先前的 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 to be 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.
这里也可以使用 EventQueue.invokeAndWait
.不同之处在于,您的计算线程会阻塞,直到您的 GUI 更新.所以很明显,这不能在 EDT 中使用.
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.
小心不要从不同的线程更新您的 Swing GUI.在大多数情况下,这会产生一些奇怪的更新/刷新问题.
Be careful not to update your Swing GUI from a different thread. In most cases this produces some strange updating/refreshing issues.
仍然有 Java 代码可以从主线程简单地启动 JFrame.这可能会导致问题,但不会阻止 Swing.大多数现代 IDE 现在创建类似这样的东西来启动 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:
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new NewJFrame().setVisible(true);
}
});
}
相关文章