转自http://www.codeceo.com/article/swing-swingutilities-invokelater.html
译者注:本文其实是一个各方见解评论的总结,已将其中于此处发布不妥的内容去掉,全文内容可查看原文。
在官方的文档里:http://docs.oracle.com/javase/tutorial/uiswing/painting/step1.html 告诉我们如何创建一个gui。
事件分发线程:
Swing中事件处理和绘画代码都在一个单独的线程中执行,这个线程就叫做事件分发线程。这就确保了事件处理器都能串行的执行,并且绘画过程不会被事件打断。为了避免死锁的可能,你必须极度小心从事件分发线程中创建、修改、查询Swing组件以及模型。
注意:我们过去常说只要你没有修改已经实现过的组件,你就能在主进程中创建GUI。[补充:下面页注中的红色字体。] 已实现过的意思是组件已经在屏幕上描绘出来或是准备描绘了。方法setVisible(true)和pack可以实现一个窗口,反过来又可以实现该窗口内 包含的组件。尽管这对大多数应用程序都管用,但这种做法在某些情况下会引起一些问题。在Swing Tutorial的所有示例中,我们只在ComponentEventDemo中遇到一个问题。在那个样例中,有时候当你载入样例后,它并不会启动。因为 如果在文本域还没实现的时候就去更新会出现死锁,但是其他的时候没有意外的话它也是会正常启动。
为了避免线程问题,建议你使用invokeLater在事件分发线程中为所有新应用程序创建GUI。如果你的现有程序能工作正常,那你可能就会让它保持下去;然而,如果改造起来方便的话,还是希望你能改造一下。
你可能已经注意 到,大部分教程中的例子都使用一个标准的主函数,即SwingUtilities的函数invokeLater来保证GUI在事件分发线程中创建。这里有 一个从FocusConceptsDemo例子中提取的主函数的样例。我们还将处理创建GUI事件的主函数都要调用的一个私有静态方法,即 createAndShowGUI 的源代码包含进来了。
/** * Create the GUI and show it. For thread safety, * this method should be invoked from the * event-dispatching thread. */ private static void createAndShowGUI() { //Make sure we have nice window decorations. JFrame.setDefaultLookAndFeelDecorated(true); //Create and set up the window. frame = new JFrame("FocusConceptsDemo"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //Create and set up the content pane. JComponent newContentPane = new FocusConceptsDemo(); newContentPane.setOpaque(true); //content panes mu