Swing组件集合的事件处理(二)

  为了提高其效率并降低其复杂性,所有的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.*; publicclass ButtonSample { publicstaticvoid main(String args[]) { Runnable runner = new Runnable() { publicvoid run() { JFrame frame = new JFrame("Button Sample"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOS E); JButton button = new JButton("Select Me"); // Define ActionListener ActionListener actionListener = new ActionListener() { publicvoid 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); } }
  代码所生成的按钮如图2-3所示:
  
  首先,我们来看一下invokeLater()方法。他需要一个Runnable对象作为参数。我们创建一个Runnable对象并传递给invokeLater()方法。在当前事件分发完成之后,Runnable对象就会执行。 如果我们希望我们的Swing GUI创建是线程安全的,那么我们所有的Swing代码就应该遵循这种模式。如果我们需要访问命令行参数,只需要在参数声明前添加final关键字就可以了:public static void main(final String args[])。这看起已经超出了一个简单的示例,但是这可以保证我们程序的线程安全性,确保所有的Swing组件的访问都是通过事件分发线程完成的。(然而调用repaint(),revalidate()以及invalidate()并不需要通过事件分发线程完成。)
  列表2-1中另外一个需要解释的代码行就是 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOS E);
  在默认情况下,如果我们图2-3中所示的容器中标题栏上的小X,程序并不会关闭;相反,框架会不可见。将默认的关闭操作设置为JFrame.EXIT_ON_CLOSE可以使得程序在会用户点击X时关闭。在第8章中我们探讨JFrame类时我们会了解到更多的信息。
  Swing组件集合包含了一个名为SwingUtilities的工具类,这个类提供了一个通用帮助方法集合。在本书中,当这个类的特定方法集合起来有用时,我们会间断的遇到这个类。对于列表2-1中的按钮示例,我们所感兴趣的方法是与确定选中哪个鼠标按钮相关的方法。
  MouseInputListener接口由七个方法组成:mouseClick(MouseEvent), mouseEntered(MouseEvent), mouseExited(MouseEvent), mousePressed(MouseEvent)以及MouseListener中的mouseRelease(MouseEvent),MouseMotionListener中的mouseDragged(MouseEvent)与mouseMove(MouseEvent)。如果我们需要确定当事件发生时哪一个鼠标按钮被选中(或是释放),我们可以检测MouseEvent的modifiers属性,并将其与InputEvent类中的各种掩码设置常量进行对比。
  例如,要检测鼠标按下事件中是否是鼠标中键被按下,我们可以在我们的鼠标监听器mousePressed()方法中使用下面的代码: 尽管这种方法可以工作得很好,然而SwingUtilities类提供三个方法可以使得这个过程更为简单: 现在我们不需要手动获取标识并与掩码进行对比,我们可以请求SwingUtilities来完这些工作,如下所示: 这可以使得我们的代码变得更容易阅读与维护。
  列表2-2包含了一个更新的ButtonSample,在其中添加了另一个监听器来检测哪一个鼠标按钮被按下。 /** * */package swingstudy.ch02; import java.awt.BorderLayout; import java.awt.EventQueue; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.InputEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.SwingUtilities; /** * @author lenovo * */publicclass ButtonSample2 { /** * @param args */publicstaticvoid main(String[] args) { // TODO Auto-generated method stub Runnable runner = new Runnable() { publicvoid run() { JFrame frame = new JFrame("Button Sample"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOS E); JButton button = new JButton("Select Me"); ActionListener actionListener = new ActionListener() { publicvoid actionPerformed(ActionEvent event) { System.out.println("I was selected"); } }; MouseListener mouseListener = new MouseAdapter() { publicvoid mousePressed(MouseEvent event) { int modifiers = event.getModifiers(); if((modifiers & InputEvent.BUTTON1_MASK) == InputEvent.BUTTON1_MASK) { System.out.println("Left button is pressed"); } if((modifiers & InputEvent.BUTTON2_MASK) == InputEvent.BUTTON2_MASK) { System.out.println("Middle button is pressed"); } if((modifiers & InputEvent.BUTTON3_MASK) == InputEvent.BUTTON3_MASK) { System.out.println("Right button is pressed"); } } publicvoid mouseReleased(MouseEvent event) { if(SwingUtilities.isLeftMouseButton(event)) { System.out.println("Left button is released"); } if(SwingUtilities.isMiddleMouseButton(event)) { System.out.println("Middle button is released"); } if(SwingUtilities.isRightMouseButton(event)) { System.out.println("Right button is released"); } } }; button.addActionListener(actionListener); button.addMouseListener(mouseListener); frame.add(button, BorderLayout.SOUTH); frame.setSize(300,100); frame.setVisible(true); } }; EventQueue.invokeLater(runner); } }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值