java.awt.EventQueue.invokeLater解释

我很好奇为什么我们必须使用java.awt.EventQueue.invokeLater来控制摆动组件。

为什么我们不能在正常的线程中做到这一点? 幕后究竟发生了什么? 从我注意到,如果我有一个JFrame我可以设置从主线程的真实或错误的可见性没有得到任何错误,它似乎工作。 那么,我通过使用java.awt.EventQueue.invokeLater到底是什么? 我也完全知道,我可以使用SwingUtilities.invokeLater但在这里解释 ,他们似乎是一回事。

感谢任何人的解释。 希望这是一个有效的问题。

编辑:回答wumpz问题我们可以创build一个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); 

在同一个线程上创build了以下内容。

 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。

这里的方法是在不同的线程中处理你的计算,所以你的GUI保持响应。 最后,你想要更新你的GUI,这些必须在EDT内完成。 现在EventQueue.invokeLater进场了。 它在Swings事件列表的末尾发布一个事件(您的Runnable ),并在所有之前的GUI事件被处理之后处理。

此外, EventQueue.invokeAndWait的使用也是可能的。 不同的是,你的计算线程阻塞,直到你的GUI更新。 所以很明显,这不能从EDT使用。

请注意不要从其他线程更新您的Swing GUI。 在大多数情况下,这会产生一些奇怪的更新/刷新问题。

仍然有Java代码在那里,从主线程启动一个简单的JFrame。 这可能会导致问题,但不会阻止Swing。 大多数现代IDE现在创build这样的东西来启动GUI:

 public static void main(String args[]) { java.awt.EventQueue.invokeLater(new Runnable() { public void run() { new NewJFrame().setVisible(true); } }); } 

所有支持的平台都提供单线程graphics库。 Swing是跨平台的。 因此,Swing GUI对象只能在事件派发线程上构造和操作。

另外, SwingUtilities.invokeLater()是自1.3版以来的EventQueue.invokeLater()的封面。