Module  java.desktop

Package javax.swing

提供一套“轻量级”(全Java语言)组件,尽可能地在所有平台上工作。 有关使用这些组件的程序员指南,请参阅“Java教程” Creating a GUI with JFC/Swing 有关其他资源,请参阅Related Documentation

Swing's Threading Policy

一般来说Swing不是线程安全的。 除非另有说明,所有Swing组件和相关类都必须在事件分派线程上访问。

典型的Swing应用程序响应于从用户手势产生的事件进行处理。 例如,点击一个JButton通知所有ActionListeners加入JButton 由于从用户手势生成的所有事件都在事件分派线程上调度,因此大多数开发人员不受该限制的影响。

然而,影响在何处,正在构建和展示Swing应用程序。 调用应用程序的main方法,或方法Applet ,没有事件调度线程上调用。 因此,在构建和显示应用程序或小应用程序时,必须注意将控件转移到事件调度线程。 转移控制并开始使用Swing的首选方法是使用invokeLater invokeLater方法调度要在事件分派线程上处理的Runnable 以下两个示例同样适用于传输控制和启动Swing应用程序:

  import javax.swing.SwingUtilities;

 public class MyApp implements Runnable {
     public void run() {
         // Invoked on the event dispatching thread.
         // Construct and show GUI.
     }

     public static void main(String[] args) {
         SwingUtilities.invokeLater(new MyApp());
     }
 } 
要么:
  import javax.swing.SwingUtilities;

 public class MyApp {
     MyApp(String[] args) {
         // Invoked on the event dispatching thread.
         // Do any initialization here.
     }

     public void show() {
         // Show the UI.
     }

     public static void main(final String[] args) {
         // Schedule a job for the event-dispatching thread:
         // creating and showing this application's GUI.
         SwingUtilities.invokeLater(new Runnable() {
             public void run() {
                 new MyApp(args).show();
             }
         });
     }
 } 
此限制也适用于与Swing组件相连的模型。 例如,如果TableModel附加到JTable ,则TableModel应仅在事件分派线程上进行修改。 如果您在单独的线程上修改模型,则会冒有异常和可能的显示损坏的风险。

由于所有事件都是在事件调度线程上传递的,所以事件处理中必须注意。 特别地,在事件分派线程上执行的诸如网络io或计算密集处理的长时间运行的任务阻止事件分派线程调度任何其他事件。 当事件调度线程被阻止时,应用程序对用户输入完全没有响应。 有关使用Swing进行此类处理的首选方法,请参阅SwingWorker

关于这个主题的更多信息可以在发现Swing tutorial ,特别是部分上Concurrency in Swing

Related Documentation

有关概述,教程,示例,指南和其他文档,请参阅: