javaSwing_6事件处理机制

Swing GUI启动后,Java虚拟机就启动三个线程,分别为主线程,事件派发线程(也是事件处理线程)和系统工具包线程。

  • 主线程 :负责创建并显示该程序的初始界面;
  • 系统工具包线程 :负责将从系统事件队列捕获在该程序界面上的鼠标和键盘操作等底层事件,并把这些事件转换成

       Swing的相应对应事件对象放入Swing的事件队列中,并循环该线程;

  • 事件派发线程 :负责GUI组件的绘制和更新,通过不断从事件队列中获取事件并调用事件监听器的事件处理方法来

这样我们就要通过专门的swing事件分发线程提交要执行的任务,这么做可以有效的解决界面部分的冲突和死锁现象。通过SwingUtilities.invokerLater()来启动一个单独的线程实现。就是所有的关于界面的操作放到一个单独的线程去做。示例代码

import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class SwingConsol {

	public static void run(final JFrame f, final int width, final int height) {
		SwingUtilities.invokeLater(new Runnable(){
			public void run(){
				f.setTitle(f.getClass().getSimpleName());
				f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
				f.setSize(width, height);
				f.setVisible(true);
				WindowTool.centerWindow(f);
			}
		});
	}
}


swing的事件处理机制其实就是一个委托事件处理,是由事件源(组件)、事件(Event)、监听器(Listener)和 事件处理器(引发事件后的处理方式)组成

  1. 事件源:

    产生事件的组件就叫事件源。


  2. 事件:

    事件是一个操作(通常使用各种输入设备,如键盘、鼠标等来完成)。

    当一个事件发生时,该事件用一个事件对象来表示。

    事件可以被大致分为两类:

    • 前台事件 - 这些事件需要用户直接互动。在图形用户界面中的图形组件交互的人产生的后果。例如,点击一个按钮,移动鼠标,通过键盘输入一个字符,从列表中选择一个项目,滚动页面等

    • 后台事件 - 这些事件,需要最终用户的交互是已知的作为背景的事件。操作系统的中断,硬件或软件故障,定时器到期时,操作完成的背景事件的例子。


    事件都包括在java.awt.event和javax.swing.event两个包中。

    java.awt.Event类已废弃,只可用于向后兼容。它已经由 AWTEvent 类及其子类所取代。

    java.util.EventObject是所有事件的超类。

    java.awt.AWTEvent是所有AWT事件类的超类。


  3. 监听器:

    包含事件处理,并负责检查事件是否发生,若发生就激活事件处理器进行处理的类叫做事件监听类,其实例就是事件监听对象。事件监听器必须实现事件监听器接口或者继承事件监听器适配类。

    java.util.EventListener是所有监听器要实现的接口。


  4. 事件处理器:

    事件处理器是一个接收事件对象并进行相应处理的方法。事件处理器包含在一个类中。


注册事件监听器:

为了能够让事件监听器检查某个组件是否发生了某些事件,并在发生时激活事件处理器进行相应的处理,必须在事件源上注册事件监听器。

一般是对过下面方法来完成的:

addXxxListener(XxxListener 的对象)  Xxx对应相应的事件类。

每一类事件都有一个相对应的事件监听接口,该接口定义了接收和处理事件的抽象方法。一个组件可以注册一个或者多个监听器对象,事件对象只向以注册的监听器对象报告事件的发生。

添加事件处理的四种方法;

  1. 自身类实现监听器接口

    自身类实现XxxListener接口

    注册时addXxxListener(this)

    类的成员函数覆盖相应的处理函数


  2. 一般内部类处理

    自身类里面写一个内部类(名字可以随便起InnerClass),这个内部类实现XxxListener接口

    注册时addXxxListener(new InnerClass())

    缺点是,当程序比较复杂时,需要一大串的if 语句来实现,程序代码较难阅读与维护。当然,如果处理的事件较少,这种方式比较简单

  3. 匿名内部类处理

    在注册时,直接实例一个匿名内部类来实例化一个监听器。

    addActionListener(new ActionListener() {
          // 事件处理
          @Override
          public void actionPerformed(ActionEvent e) {
            Container c = getContentPane();
            c.setBackground(Color.BLUE);
          }
        });

    优缺点:首先,根据组件在代码中被定义的不同位置,类的定义以及处理事件的代码将分散在程序的各个部分,不是集中在一块,同样不便于阅读与维护。各事件的处理全部由嵌套的程序块组成,视觉上很难定位程序代码。如果事件处理程序比较复杂,内部类中的代码将变得很长,你将找不到相应的组件定义位置。最后,当工具栏、菜单栏目等需要处理同样的用户行为时,该方法将使代码更难维护。
  4. 命名内部类
    利用一般内部类来监听每一个事件源产生的事件如(button1, button2)
    private class Button1Handler implements ActionListener {
    
                  public void actionPerformed(ActionEvent e) {
    
                         JOptionPane.showMessageDialog(frame, "按钮1 被点击");
    
                  }
    
           }
    // 对每一个组件注册监听内部类
    
                  button1.addActionListener(new Button1Handler());
    
                  button2.addActionListener(new Button2Handler());

    所有的事件处理方法都集中在一块,并且都具有有意义的名称,程序非常容易阅读与维护。单个的事件处理程序也可以被工具栏、菜单栏等重复使用。

  5. 外部类处理

    在自身类外面写一个外部类(名字可以随便起OutClass),这个外部类实现XxxListener接口

    注册时addXxxListener(new OutClass(。。。))



常用事件和监听器

事件   监听器接口 适配器 事件处理方法
组件类事件(当组件的状态发生变化时产生)
ComponentEvent 操作某组件时 ComponentListener ComponentAdapter componentHidden
componentMoved
componentResized
componentShown
ContainerEvent 向容器添加或者删除组件时 ContainerListener ContainerAdapter componentAdded
componentRemoved
WindowEvent 操作窗口时发生的事件,如最大化或者最小化窗口 WindowListener WindowAdapter windowActivated
windowClosed
windowClosing
windowDeactivated
windowDeiconified
windowIconified
windowOpened
FocusEvent   FocusListener FocusAdapter focusGained
focusLost
PaintEvent        
MouseEvent 操作鼠标时 MouseListener MouseAdpater mouseClicked
mouseEntered
mouseExited
mousePressed
mouseReleased
动作类事件(他们均对应用户的某一功能性操作动作)
ActionEvent 激活组件时发生 ActionListener   actionPerformed
adjustmentEvent 调节可调整的组件时 adjustmentListener   adjustmentValueChanged
TextEvent 更改文本时 TextListener   textValueChanged
ItemEvent 从选择项、复选框或者列表中选择是发生 ItemListener   itemStateChanged
         
KeyEvent 操作键盘时 KeyListener KeyAdapter keyPressed
keyReleased
keyTyped
MouseMotionEvent   MouseMotionListener MouseMotionAdpater mouseDragged
mouseMoved
InputEvent 由某输入设备产生      
         
         


详解:

java.util.EventObject

是所有事件的超类。


字段摘要
protected  Object source
          最初发生 Event 的对象。
 
构造方法摘要
EventObject(Object source)
          构造一个原型 Event。
 
方法摘要
 Object getSource()
          最初发生 Event 的对象。
 String toString()
          返回此 EventObject 的 String 表示形式。
 

java.awt.AWTEvent

所有 AWT 事件的根事件类。此类及其子类取代了原来的 java.awt.Event 类。此根 AWTEvent 类(在 java.awt.event 包的外部定义)的子类定义的事件 ID 值应该大于 RESERVED_ID_MAX 定义的值。

字段摘要
static long ACTION_EVENT_MASK
          用于选择操作事件的事件掩码。
static long ADJUSTMENT_EVENT_MASK
          用于选择调整事件的事件掩码。
static long COMPONENT_EVENT_MASK
          用于选择组件事件的事件掩码。
protected  boolean consumed
          在源处理了事件之后,控制是否将事件发送回同位体,false 表示将事件发送给同位体;true 则不发送。
static long CONTAINER_EVENT_MASK
          用于选择容器事件的事件掩码。
static long FOCUS_EVENT_MASK
          用于选择焦点事件的事件掩码。
static long HIERARCHY_BOUNDS_EVENT_MASK
          用于选择层次结构边界事件的事件掩码。
static long HIERARCHY_EVENT_MASK
          用于选择层次结构事件的事件掩码。
protected  int id
          事件的 id。
static long INPUT_METHOD_EVENT_MASK
          用于选择输入方法事件的事件掩码。
static long INVOCATION_EVENT_MASK
          用于选择调用事件的事件掩码。
static long ITEM_EVENT_MASK
          用于选择项事件的事件掩码。
static long KEY_EVENT_MASK
          用于选择键事件的事件掩码。
static long MOUSE_EVENT_MASK
          用于选择鼠标事件的事件掩码。
static long MOUSE_MOTION_EVENT_MASK
          用于选择鼠标动作事件的事件掩码。
static long MOUSE_WHEEL_EVENT_MASK
          用于选择鼠标滚轮事件的事件掩码。
static long PAINT_EVENT_MASK
          用于选择绘制事件的事件掩码。
static int RESERVED_ID_MAX
          保留的 AWT 事件 ID 的最大值。
static long TEXT_EVENT_MASK
          用于选择文本事件的事件掩码。
static long WINDOW_EVENT_MASK
          用于选择窗口事件的事件掩码。
static long WINDOW_FOCUS_EVENT_MASK
          用于选择窗口焦点事件的事件掩码。
static long WINDOW_STATE_EVENT_MASK
          用于选择窗口状态事件的事件掩码。

构造方法摘要
AWTEvent(Event event)
          从 1.0 样式的事件参数构造一个 AWTEvent 对象。
AWTEvent(Object source, int id)
          使用指定的源对象和类型构造一个 AWTEvent 对象。
 
方法摘要
protected  void consume()
          如果能够使用此事件,则使用此事件。
 int getID()
          返回事件类型。
protected  boolean isConsumed()
          返回是否已经使用了此事件。
 String paramString()
          返回表示此 Event 状态的字符串。
 void setSource(Object newSource)
          将事件的目标更改为新的源。
 String toString()
          返回此对象的字符串表示形式。


java.util.EventObject

AWTEvent

ActionEvent

AdjustmentEvent

AncestorEvent

ComponentEvent

ContainerEvent

FocusEvent

InputEvent

KeyEvent

MouseEvent

MenuDragMouseEvent

MouseWheelEvent

PaintEvent

WindowEvent

HierarchyEvent

InputMethodEvent

InternalFrameEvent

InvocationEvent

ItemEvent

TextEvent

CaretEvent

ChangeEvent

HyperlinkEvent

LineEvent

MenuEvent

Notification

PopupMenuEvent

PrintEvent

PropertyChangeEvent

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------




  1. ActionEvent(动作事件)


    监听器: ActionListener

    actionPerformed(ActionEvent e)


    事件的方法:

    String getActionCommand() actioncommand 是控件内部的一个字符串,用于标识控件的状态。此函数可以 取得控件的状态,从而决定到底该做什么。

    int getModifiers() 取得 “ 产生此事件时,用户同时按下的组合键 ”

    long getWhen() 取得 “ 产生此事件时的时间戳 ”


    事件产生原因: 点击按钮,在列表框中选择内容,在文本框中点回车, 计时器到期

    比如按钮只要是按下就会出现此事件,不用关心是键盘的空格键触发的还是鼠标按下的。


  2. java.awt.event.AdjustmentEvent

    监听器: AdjustmentListener

    adjustmentValueChanged

    方法:

    ● Adjustable getAdjustable() adjustable 是一个接口,各种滚动条都实现了这个接口。

    ● int getAdjustmentType() 取得滚动类型,共有 UNIT_INCREMENT , UNIT_DECREMENT , BLOCK_INCREMENT , BLOCK_DECREMENT , TRACK 共 5 种类型

    ● int getValue() 取得滚动滑块的当前值


    事件产生原因: 滚动条的滚动


  3. java.awt.event.ItemEvent

    监听器: ItemListener

    itemStateChanged


    方法:

    ● Objedt getItem() 取得被选中的元素。注意,返回值是 Object ,还应该进行强制类型转换。

    ● ItemSelectable getItemSelectable()

    ItemSelectable 是一个接口, 代表那些包含了 n 个可供选择的子元素的对象。 此 方法返回产生此事件的对象。 此方法的作用主要在于, 如果一个列表框是允许多 选的, 那么上面的方法就不好用了, 应该用此方法得到列表对象, 再取得被选中 的多个元素。

    ● int getStateChange() 取得选择的状态,是 SELECTED 还是 DESELECTED


    事件产生原因: 各种按钮的点击,列表框的选择


  4. java.awt.event.TextEvent

    监听器: TextListener

    textValueChanged(TextEvent e)  文本的值已改变时调用。


    方法:

    ● Objedt getItem() 取得被选中的元素。注意,返回值是 Object ,还应该进行强制类型转换。

    ● ItemSelectable getItemSelectable()

    ItemSelectable 是一个接口, 代表那些包含了 n 个可供选择的子元素的对象。 此 方法返回产生此事件的对象。 此方法的作用主要在于, 如果一个列表框是允许多 选的, 那么上面的方法就不好用了, 应该用此方法得到列表对象, 再取得被选中 的多个元素。

    ● int getStateChange() 取得选择的状态,是 SELECTED 还是 DESELECTED


    事件产生原因:文本改变时

    事件发生时,实现 TextListener 接口的对象获得此 TextEvent。侦听器不必考虑个别鼠标移动和击键的细节,而是可以处理像“文本改变”这样的“有意义”(语义)事件。


  5. java.awt.event.ComponentEvent

    监听器:ComponentListener

    方法摘要
     void componentHidden(ComponentEvent e)
              组件变得不可见时调用。
     void componentMoved(ComponentEvent e)
              组件位置更改时调用。
     void componentResized(ComponentEvent e)
              组件大小更改时调用。
     void componentShown(ComponentEvent e)
              组件变得可见时调用。

    ComponentAdapter

    方法摘要
     void componentHidden(ComponentEvent e)
              组件变得不可见时调用。
     void componentMoved(ComponentEvent e)
              组件位置更改时调用。
     void componentResized(ComponentEvent e)
              组件大小更改时调用。
     void componentShown(ComponentEvent e)
              组件变得可见时调用

    事件方法:

    Component getComponent() 返回事件的始发者



  6. java.awt.event.ContainerEvent

    监听器:ContainerListener

    方法摘要
     void componentAdded(ContainerEvent e)
              已将组件添加到容器中时调用。
     void componentRemoved(ContainerEvent e)
              已从容器中移除组件时调用。

    ContainerAdapter

    方法摘要
     void componentAdded(ContainerEvent e)
              已将组件添加到容器中时调用。
     void componentRemoved(ContainerEvent e)
              已从容器中移除组件时调用。

    事件方法:

     Component getChild()
              返回受事件影响的组件。
     Container getContainer()
              返回事件的始发者。


    事件产生原因:添加删除组件


  7. java.awt.event.FocusEvent

    监听器: FocusListener

    focusGained

    focusLost


    事件方法:

    ● Component getOppositeComponent() 得到 “ 参与焦点变换的 ” 另一个对象。如果是焦点取得事件,则返回之前拥有焦点 的对象; 如果是焦点失去事件, 则返回得到焦点的对象。 若焦点转移到另外一个 应用程序,返回 null

    ● boolean isTemporary() 焦点是临时性转移还是永久转移。 临时性转移: 用鼠标拖动窗口或者窗口变为非 激活状态。其他为永久性转移。


    事件产生原因: 各种组件的焦点变化

  8. java.awt.event.InputEvent

    所有组件级别输入事件的根事件类。 输入事件通常由产生输入事件的源代码进行处理,而在此之前,将他们提交到侦听器中。这样就允许侦听器和组件子类“使用”事件,以便源代码不会以默认方式处理事件。例如,在 Button 组件上使用 mousePressed 事件将阻止 Button 被激活。

    字段摘要
    static int ALT_DOWN_MASK
              Alt 键的扩展修饰符常量。
    static int ALT_GRAPH_DOWN_MASK
              AltGraph 键的扩展修饰符常量。
    static int ALT_GRAPH_MASK
              AltGraph 键修饰符常量。
    static int ALT_MASK
              Alt 键修饰符常量。
    static int BUTTON1_DOWN_MASK
              Mouse Button1 的扩展修饰符常量。
    static int BUTTON1_MASK
              Mouse Button1 修饰符常量。
    static int BUTTON2_DOWN_MASK
              Mouse Button2 的扩展修饰符常量。
    static int BUTTON2_MASK
              Mouse Button2 修饰符常量。
    static int BUTTON3_DOWN_MASK
              Mouse Button3 的扩展修饰符常量。
    static int BUTTON3_MASK
              Mouse Button3 修饰符常量。
    static int CTRL_DOWN_MASK
              Control 键的扩展修饰符常量。
    static int CTRL_MASK
              Ctrl 键修饰符常量。
    static int META_DOWN_MASK
              Meta 键的扩展修饰符常量。
    static int META_MASK
              Meta 键修饰符常量。
    static int SHIFT_DOWN_MASK
              Shift 键的扩展修饰符常量。
    static int SHIFT_MASK
              Shift 键修饰符常量。

    方法摘要
     void consume()
              使用此事件,以便不会按照默认的方式由产生此事件的源代码来处理此事件。
     int getModifiers()
              返回此事件的修饰符掩码。
     int getModifiersEx()
              返回此事件的扩展修饰符掩码。
    static String getModifiersExText(int modifiers)
              返回描述扩展修改键和鼠标按钮(例如 "Shift"、"Button1" 或 "Ctrl+Shift")的 String。
     long getWhen()
              返回此事件发生时的时间戳。
     boolean isAltDown()
              返回 Alt 修饰符在此事件上是否为 down。
     boolean isAltGraphDown()
              返回 AltGraph 修饰符在此事件上是否为 down。
     boolean isConsumed()
              返回是否已经使用此事件。
     boolean isControlDown()
              返回 Control 修饰符在此事件上是为 down。
     boolean isMetaDown()
              返回 Meta 修饰符在此事件上是否为 down。
     boolean isShiftDown()
              返回 Shift 修饰符在此事件上是否为 down。


  9. java.awt.event.KeyEvent

    监听器: KeyListener

    keyPressed

    keyReleased

    keyTyped


    事 件方法:

    ● char getKeyChar() 此方法只在 keytyped 中有效,返回按下的字符。比如按下 shift+a ,返回 'A'

    ● int getKeyCode() 取得键盘上按键的整数编码。请注意,是键盘上的按键,比如 F1 , Ctrl , Home 键等等, 都有相应编码。 不支持组合键, 也就是说 “Shift+a” 和 “a” 返回同样的内容, 都是小写 a 的 ASCII 码。但是大键盘的数字键和小键盘的数字键返回内容不同。

    ● static String getKeyModifiersText(int modifiers) 将掩码转化为字符串,比如 “Ctrl” , “Ctrl+Shift” 等。注意它是 static 方法

    ● static String getKeyText(int keyCode) 返回 keyCode 代表的按钮的名字,比如 "Home" , "F1" 等。注意它是 statci 方法


    事件产生原因: 在各种组件上敲击键盘

  10. java.awt.event.MouseEvent

    直接已知子类:MenuDragMouseEvent, MouseWheelEvent
    监听器: MouseListener

    mouseClicked

    mousePressed

    mouseReleased

    mouseEntered

    mouseExited

    监听器: MouseMotionListener

    mouseDragged

    mouseMoved


    事 件方法:

    ● Point getLocationOnScreen() 返回鼠标相对于显示屏幕的绝对坐标( java 1.6 版提供)

    ● int getXOnScreen() 返回鼠标相对于显示屏幕的 X 的绝对坐标( java 1.6 版提供)

    ● int getYOnScreen() 返回鼠标相对于显示屏幕的 Y 的绝对坐标( java 1.6 版提供)

    ● Point getPoint() 返回鼠标相对于组件的绝对坐标

    ● int getX() 返回鼠标相对于组件的 X 的绝对坐标

    ● int getY() 返回鼠标相对于组件的 Y 的绝对坐标

    ● void translatePoint(int x, int y) 给鼠标的做用点加上一个偏移量。 比如 2 个参数分别是 10 , 20 , 你要用鼠标画 直线,当你鼠标指向 100 , 100 开始画,实际上的线是画在 110 , 120 处

    ● int getClickCount() 产生此事件时鼠标共点击了多少下(单击、双击、三击 …… )

    ● int getButton() 产生此事件时, 鼠标的哪个键被点击了: NOBUTTON, BUTTON1, BUTTON2 或 者 BUTTON3

    ● boolean isPopupTrigger() 是否能够触发一个弹出式菜单。 由于各平台触发弹出式菜单的情况不一样, 因此 应该在 mousePressed 和 mouseReleased 中都检测一下 事件产生原因: 在任何组件上点击鼠标、将光标移动进来或出去

     事 件: MouseEvent 同上!


    事件产生原因: 在任何组件上移动鼠标


  11. java.awt.event.MouseWheelEvent

    监听器: MouseWheelListener

    mouseWheelMoved

    事件方法:

    ● int getScrollType() 滚动的类型,是按块滚动 WHEEL_BLOCK_SCROLL 还是按单位滚动 WHEEL_UNIT_SCROLL

    ● int getScrollAmount() 返回为相应此事件应该滚动的单位数。此方法有效的前提是按单位滚动。

    ● int getWheelRotation() 鼠标滚轮滚动过程中 ” 咔嚓 “ 声的数目。向上滚为负值,向下滚为正值 事件产生原因: 在任何组件上滚动鼠标中键

    事件产生原因:鼠标的滚轮的滚动


  12. java.awt.event.WindowEvent

    监听器: WindowListener     事件产生原因: 窗口发生变化

    windowOpened

    windowClosing

    windowClosed

    windowIconified

    windowDeiconified

    windowActivated

    windowDeactivated

    监听器: WindowFocusListener   事件产生原因:窗口得到或失去焦点

    windowGainedFocus

    windowLostFocus

    监听器: WindowStateListener      事件产生原因: 窗口状态改变

    WindowStateChanged

    监听器:WindowAdapter

    方法摘要
     void windowActivated(WindowEvent e)
              激活窗口时调用。
     void windowClosed(WindowEvent e)
              当窗口已被关闭时调用。
     void windowClosing(WindowEvent e)
              窗口正处在关闭过程中时调用。
     void windowDeactivated(WindowEvent e)
              停用窗口时调用。
     void windowDeiconified(WindowEvent e)
              取消图标化窗口时调用。
     void windowGainedFocus(WindowEvent e)
              该 Window 被设置为聚焦 Window 时调用,聚焦 Window 意味着该 Window 或其某个子组件将接收键盘事件。
     void windowIconified(WindowEvent e)
              图标化窗口时调用。
     void windowLostFocus(WindowEvent e)
              该 Window 不再为聚焦 Window 时调用,不再为聚焦 Window 意味着键盘事件不再传递到该 Window 或其任意子组件。
     void windowOpened(WindowEvent e)
              已打开窗口时调用。
     void windowStateChanged(WindowEvent e)
              窗口状态改变时调用。

    事 件方法:

    ● Window getWindow() 返回发生此事件的 window 对象

    ● Window getOppositeWindow() 若发生了焦点转移,返回另一个参与此事件的 window 对象,或者 null

    ● int getOldState() 窗口变化前的状态: NORMAL 、 ICONIFIED 、 MAXIMIZED_BOTH

    ● int getNewState() 窗口变化后的状态




自定义事件



你可能感兴趣的:(Java)