一个好的swing程序是不会让用户有卡的感觉的,应用程序总能快速的响应用户的操作。要想保证程序不卡顿,那么就需要利用好多线程。首先需要了解swing的线程都有哪些,以及这些线程有什么作用。
swing的线程有三种:
上面说的这三种线程swing框架会帮我们创建出来,不需要我们自己new Thread,我们要做的就是使用好这三种线程。但是并不是说一个swing应用程序就只能有这三种线程,我们也可以自己new一个新的线程。下面就来详细了解这三种线程的用途和用法。
一个应用程序可能会有多个线程,但是只会有一个线程执行main方法,那个线程就称为初始化线程。在swing程序中,初始化线程一般不会做太多的工作,它的主要工作是创建一个Runnable对象用于初始化GUI和编排执行在事件线程中的对象如事件监听器,一旦GUI创建出来之后,程序就主要由GUI事件驱动了如按钮点击事件。一般执行时间比较的任务放在事件线程中执行,而执行时间较长的任务放在工作线程中执行。
初始化线程通过javax.swing.SwingUtilities.invokeLater或javax.swing.SwingUtilities.invokeAndWait来编排GUI创建任务。这两个方法都接收一个Runnable对象,该对象包含了要执行创建GUI的代码。它们的区别是invokeLater是立即返回的,而invokeAndWait需要Runnable执行完成之后才能返回。
- SwingUtilities.invokeLater(new Runnable() {
- public void run() {
- createAndShowGUI();
- }
- });
在applet程序中,必须使用invokeAndWait来执行GUI创建的任务, 那是为了防止GUI还没有创建初始化线程就已经执行完了,从而可能导致程序已经退出了。
为什么不在初始化线程中创建GUI呢?因为创建swing组件的代码,和与swing组件交互的代码需要在事件线程中执行。
事件处理程序运行在事件线程,大多数的swing方法也运行在事件线程,那是因为大多数的swing对象的方法不是线程安全的。对于标注了thread safe的swing方法是可以在其他线程中执行的。
事件线程的任务一般是小儿快的,否则就有可能造成卡顿的情况出现。
要使用代码执行在事件线程,可以使用invokeLater或invokeAndWait方法,但是事件处理代码不需要用这两个方法,如ActionListener.actionPerformed。
javax.swing.SwingUtilities.isEventDispatchThread用于判断当前线程是否是事件线程。