为了提高其效率并降低其复杂性,所有的Swing组件都被设计为非线程安全的。尽管这听起比较恐怖,他只是简单的意味着对Swing组件的所有访问需要由一个单一线程完成--事件分发线程。如果我们并不确定我们位于一个特定的线程中,我们可以使用public static boolean isDispatchThread()方法请求EventQueue类或是通过public static boolean isEventDispatchThread()方法请求SwingUtilities类。后者只是作为前者的代理。
通过EventQueue类的帮助,我们可以创建Runnable对象在事件分发线程上执行来正确的访问组件。如果我们需要在事件分发线程上执行一个任务,但是我们并不需要结果也不会关心任务何时完成时,我们可以使用EventQueue的public static void invokeLater(Runnable runnable)方法。如果是相反的情况,直到任务结束并返回值时我们才能继承我们的工作,我们可以使用EventQueue的public static void invokeAndWait(Runnable runnable)方法。获取值的代码要由我们来完成,而并不是invokeAndWait()方法的返回值。
为了演示创建一个基于Swing程序的正确方法,列表2-1演示了一个用于可选中按钮的源代码。
import javax.swing.*; import java.awt.*; import java.awt.event.*; public class ButtonSample { public static void main(String args[]) { Runnable runner = new Runnable() { public void run() { JFrame frame = new JFrame("Button Sample"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JButton button = new JButton("Select Me"); // Define ActionListener ActionListener actionListener = new ActionListener() { public void actionPerformed(ActionEvent actionEvent) { System.out.println("I was selected."); } }; // Attach listeners button.addActionListener(actionListener); frame.add(button, BorderLayout.SOUTH); frame.setSize(300, 100); frame.setVisible(true); } }; EventQueue.invokeLater(runner); } }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)