第8章 事件处理

本章内容:
* 事件处理基础
* 动作
* 鼠标事件
* AWT事件继承层次

8.1 事件处理基础

  1. 在AWT所知的事件范围内,完全可以控制事件从事件源(event source)例如,按钮或滚动条,到事件监听器(event listener)的传递过程,并将任何对象指派给事件监听器。不过事实上,应该选择一个能够便于响应事件的对象。这种事件委托模型(event delegation event)与Visual Basic那种预定义监听器模型比较起来更加灵活。
  2. 事件源有一些向其注册事件监听器的方法。当某个事件源产生事件时,事件源会向为事件注册的所有事件监听器对象发送一个通告。
  3. 像Java这样的面向对象语言,都将事件的相关信息封装在一个事件对象(event object)中。在Java中,所有的事件对象都最终派生于java.util.EventObject类。
  4. 不同的事件源可以产生不同类别的事件。
  5. AWT事件处理机制的概要:
    • 监听器对象是一个实现了特定监听器接口(listener interface)的类的实例。
    • 事件源是一个能够注册监听器对象并发送事件对象的对象。
    • 当事件发生时,事件源将事件对象传递给所有注册的监听器。
    • 监听器对象将利用事件对象中的信息决定如何对事件做出响应。

8.1.1 实例:处理按钮点击事件

  1. 可以通过在按钮构造器中指定一个标签字符串、一个图标或两项都指定来创建一个按钮。
  2. ActionListener接口并不仅限于按钮点击事件。它可以应用于很多情况:
    • 当采用鼠标双击的方式选择了列表框中的一个选项时;
    • 当选择一个菜单项时;
    • 当在文本域中按回车键时;
    • 对于一个Timer组件来说,当达到指定的时间间隔时。
      在所有这些情况下,使用ActionListener接口的方式都是一样的:actionPerformed方法(ActionListener中的唯一方法)将接收一个ActionEvent类型的对象作为参数。这个事件对象包含了事件发生时的相关信息。
  3. 事件监听器对象通常需要执行一些对其他对象可能产生影响的操作。可以策略性地将监听器类放置在需要修改状态的那个类中。
  4. jaxax.swing.JButton 1.2
    • JButton(String label)
    • JButton(Icon icon)
    • JButton(String label,Icon icon)
      构造一个按钮,标签可以是常规的文本,从Java1.3开始,也可以是HTML。
  5. java.awt.Container 1.0
    • Component add(Component c)
      将组件c添加到这个容器中。

8.1.2 建议使用内部类

  1. 内部类机制将自动地生成一个构造器,其中存储着所有用在内部类方法中的final局部变量。
  2. java.util.EventObject 1.1
    • Object getSource()
      返回发生事件的对象引用。
  3. java.awt.event.ActionEvent 1.1
    • String getActionCommand()
      返回与这个动作事件相关的命令字符串。如果动作事件来源于按钮,命令字符串就等于按钮标签,除非已经使用setActionCommand方法对字符串进行了修改。

8.1.3 创建包含一个方法调用的监听器

  1. EventHandler类可以使用下列调用,自动地创建这样一个监听器:EventHandler.create(ActionListener.class,frame,"loadData")
  2. java.beans.EventHandler 1.4
    • static Object create(Class listenerInterface,Object target,String action)
    • static Object create(Class listenerInterface,Object target, String action,String eventProperty)
    • static Object create(Class listenerInterface,Object target,String action,String eventProperty,String listenerMethod)
      构造实现给定接口的一个代理类对象。命名方法或接口的所有方法都将在目标对象上执行给定动作。
      这个动作可以是一个方法名或目标的一个属性。如果是一个属性,将执行其设置方法。
      事件属性包括一个或多个用点号分割的属性名。第一个属性从监听器方法的参数读取,第二个属性由结果对象读取,依次类推。最后的结果将作为动作的参数。

8.1.4 实例:改变观感

  1. 在默认情况下,Swing程序使用Metal观感,可以采用两种方式改变观感。第一种方式是在Java安装的子目录jre/lib下有一个文件swing.properties。在这个文件中,将属性swing.defaultlaf设置为所希望的观感类名。
    注意,Metal观感位于javax.swing包中。其他的观感位于com.sun.java包中,并且不是在每个Java实现中都提供。现在,鉴于版权的原因,Windows和Macintosh的观感包只与Windows和Macintosh版本的Java运行时环境一起发布。
    第二种方式是动态地改变观感。这需要调用静态的UIManager.setLookAndFeel方法,并提供所想要的观感类名,然后再调用静态方法SwingUtilities.updateComponentTreeUI来刷新全部的组件集。这里需要向这个方法提供一个组件,并由此找到其他的所有组件。当UIManager.setLookAndFeel方法没有找到所希望的观感或在加载过程中出现错误时,将会抛出异常。
  2. javax.swing.UIManager 1.2
    • static UIManager.LookAndFeelInfo[] getInstalledLookAndFeels()
      获取一个用于描述已安装的观感实现的对象数组。
    • static setLookAndFeel(String className)
      利用给定的类名设置当前的观感。例如,javax.swing.plaf.MetalLookAndFeel。
  3. javax.swing.UIManager.LookAndFeelInfo 1.2
    • String getName()
      返回观感的显示名称。
    • String getClassName()
      返回观感实现类的名称。

8.1.5 适配器类

  1. 为了能够查看窗口是否被最大化,需要安装WindowStateListener。
  2. 每个含有多个方法的AWT监听器接口都配有一个适配器(adapter)类,这个类实现了接口中的所有方法,但每个方法没有做任何事情。这意味着适配器类自动满足了Java实现相关监听器接口的技术需求。可以通过扩展适配器类来指定对某些时间的响应动作,而不必实现接口中的每个方法。
  3. java.awt.event.WindowListener 1.1
    • void windowOpened(WindowEvent e)
      窗口打开后调用这个方法。
    • void windowClosing(WindowEvent e)
      在用户发出窗口管理器命令关闭窗口时调用这个方法。需要注意的是,仅当调用hide或dispose方法后窗口才能够关闭。
    • void windowClosed(WindowEvent e)
      窗口关闭后调用这个方法。
    • void windowIconified(WindowEvent e)
      窗口图标化后调用这个方法。
    • void windowDeiconified(WindowEvent e)
      窗口非图标化后调用这个方法。
    • void windowActivated(WindowEvent e)
      激活窗口后调用这个方法。只有框架或对话框可以被激活。通常,窗口管理器会对活动窗口进行修饰,比如,高亮度标题栏。
    • void windowDeactivated(WindowEvent e)
      窗口变为未激活状态后调用这个方法。
    • void windowStateChanged(WindowEvent event)
      窗口最大化、图标化或恢复为正常大小时调用这个方法。
    • int getNewState()1.4
    • int getOldState() 1.4
      返回窗口状态改变事件中窗口的新、旧状态。返回的整型数值是下列数值之一:Frame.NORMAL、Frame.ICONIFIED、Frame.MAXIMIZED_HORIZ、Frame.MAXIMIZED_VERT、Frame.MAXIMIZED_BOTH。

8.2 动作

  1. 通常,激活一个命令可以有多种方式。用户可以通过菜单、击键或工具栏上的按钮选择特定的功能。在AWT事件模型中实现这些非常容易:将所有事件连接到同一个监听器上。
  2. Swing包提供了一种非常实用的机制来封装命令,并将它们连接到多个事件源,这就是Action接口。一个动作是一个封装下列内容的对象:
    • 命令的说明(一个文本字符串和一个可选图标);
    • 执行命令所需要的参数。
  3. Action接口扩展于ActionListener接口,因此,可以在任何需要ActionListener对象的地方使用Action对象。
  4. 预定义动作表名称
    名称
    NAME 动作名称,显示在按钮和菜单上
    SMALL_ICON 存储小图标的地方;显示在按钮、菜单项或工具栏中
    SHORT_DESCRIPTION 图标的简要说明;显示在工具提示中
    LONG_DESCRIPTION 图标的详细说明;使用在在线帮助中。没有Swing组件使用这个值
    MNEMONIC_KEY 快捷键缩写;显示在菜单项中
    ACCELERATOR_KEY 存储加速击键的地方;Swing组件不使用这个值
    ACTION_COMMAND_KEY 历史遗留;仅在旧版本的registerKeyboardAction方法中使用
    DEFAULT 常用的综合属性;Swing组件不使用这个值
  5. 如果动作对象添加到菜单或工具栏上,它的名称和图标就会被自动地提取出来,并显示在菜单栏或工具栏项中。SHORT_DESCRIPTION值变成了工具提示。
  6. Action是一个接口,而不是一个类。有一个类实现了这个接口除actionPerformed方法之外的所有方法,它就是AbstractAction。这个类存储了所有名、值对。并管理着属性变更监听器。可以直接扩展AbstractAction类,并在扩展类中实现了actionPerformed方法。
  7. 每个JComponent有三个输入映射(input maps),每一个映射的KeyStore对象都与动作关联。三个输入映射对应着三个不同的条件。
    输入映射表
    标志 激活动作
    WHEN_FOCUSED 当这个组件拥有键盘焦点时
    WHEN_ANCESTOR_OF_FOCUSED_COMPONENT 当这个组件包含了拥有键盘焦点的组件时
    WHEN_IN_FOCUSED_WINDOW 当这个组件被包含在一个拥有键盘焦点组件的窗口中时
  8. 按键处理将按照下列顺序检查这些映射:
    1)检查具有输入焦点组件的WHEN_FOCUSED映射。如果这个按键存在,将执行对应的动作。如果动作已启动,则停止处理。
    2)从具有输入焦点的组件开始,检查其父组件的WHEN_ANCESTOR_OF_FOCUSED_COMPONENT映射。一旦找到按键对应的映射,就执行对应的动作。如果动作已启用,将停止处理。
    3)查看具有输入焦点的窗口中的所有可视的和启用的组件,这个按键被注册到WHEN_IN_FOCUSED_WINDOW映射中。给这些组件(按照按键注册的顺序)一个执行对应动作的机会。一旦第一个启用的动作被执行,就停止处理。如果一个按键咋多个WHEN_IN+FOCUSED_WINDOW映射中出现,这部分处理就可能会出现问题。
  9. 可以使用getInputMap方法从组件中得到输入映射。
  10. InputMap不能直接将KeyStore对象映射到Actoin对象中。而是先映射到任意对象上,然后由ActionMap类实现将对象映射到动作上的第2个映射。这样很容易实现来自不同输入映射的按键共享一个动作的目的。
  11. 每个组件都可以有三个输入映射和一个动作映射。为了将他们组合起来,需要为动作命名。
  12. 用同一个动作响应按钮、菜单项或按键的方式:
    1)实现一个扩展于AbstractAction类的类。多个相关的动作可以使用同一个类。
    2)构造一个动作类的对象。
    3)使用动作对象创建按钮或菜单项。构造器将从动作对象中读取标签文本和图标。
    4)为了能够通过按键触发动作,必须额外地执行几步操作。首先定位顶层窗口组件,例如,包含所有其他组件的面板。
    5)然后,得到顶层组件的WHEN_ANCESTOR_OF_FOCUS_COMPONENT输入映射。为需要的按键创建一个KeyStore对象。创建一个描述动作字符串这样的动作键对象。将(按键,动作键)对添加到输入映射中。
    6)最后,得到顶层组件的动作映射。将(动作键,动作对象)添加到映射中。
  13. javax.swing.Action 1.2
    • boolean isEnabled()
    • void setEnabled(boolean b)
      获得或设置这个动作额enabled属性。
    • void putValue(String key,Object value)
      将名/值对防止在动作对象内。
      参数:key 用动作对象存储性能的名字。它可以是一个字符串,但预定义了几个名字。 value 与名字关联的对象。
    • Object getValue(String key)
      返回被存储的名/值对的值。
  14. javax.swing.KeyStore 1.2
    • static KeyStore getKeyStroke(String description)
      根据一个便于人们阅读的说明创建一个按键(由空格分割的字符串序列)。这个说明以0个或多个修饰符shift control strl meta alt altGraph开始,以由types和单个字符构成的字符串(例如:“typed a”)或者一个可选的事件说明符(pressed默认,或released)紧跟一个键码结束。以VK_前缀开始的键码应该对应一个KeyEvent常量,例如,“INSERT”对应KeyEvent.VK_INSERT。
  15. javax.swing.JComponent 1.2
    • ActionMap getActionMap() 1.3
      返回关联动作映射键(可以是任意的对象)和动作对象的映射。
    • InputMap getInputMap(int flag) 1.3
      获得将案件映射到动作键的输入映射。
      参数:flag 触发动作的键盘焦点条件。

8.3 鼠标动作

  1. 当用户点击鼠标按钮时,将会调用三个监听器方法:鼠标第一次按下时调用mousePressed;鼠标被释放时调用mouseReleased;最后调用mouseClicked。如果只对最终的点击事件感兴趣,就可以忽略前两个方法。用MouseEvent类对象作为参数,调用getX和getY方法可以获得鼠标被按下时鼠标指针所在x和y坐标。要想区分单击、双击和三击(!),需要使用getClickCount方法。
  2. getModifiersEx方法能够准确地报告鼠标事件的鼠标按钮和键盘修饰符。
  3. 在Windows环境下,使用BUTTON3_DOWN_MASK检测鼠标右键(非主要的)的状态。
  4. java.awt.event.MouseEvent 1.1
    • int getX()
    • int getY()
    • Point getPoint()
      返回事件发生时,事件源组件左上角的坐标x(水平)和y(垂直),或点信息。
    • int getClickCount()
      返回与事件关联的鼠标连击次数(“连击”所指定的时间间隔与具体系统有关)。
  5. java.awt.event.InputEvent 1.1
    • int getModifiersEx() 1.4
      返回事件扩展的或“按下”(down)的修饰符。使用下面的掩码值检测返回值:BTTON1_DOWN_MASK、BUTTON2_DOWN_MASK、BUTTON3_DOWN_MASK、SHIFT_DOWN_MASK、CTRL_DOWN_MASK、ALT_DOWN_MASK、ALT_GRAPH_DOWN_MASK、META_DOWN_MASK。
    • static String getModifiersExText(int modifiers) 1.4
      返回用给定标志集描述的扩展或“按下”(down)的修饰符字符串,例如“Shift+Button1”。
  6. java.awt.Toolkit 1.0
    • public Cursor createCustomCursor(Image image,Point hotSpot,String name) 1.2
      创建一个新的定制光标对象。
      参数:image 光标活动时显示的图像。hotSpot 光标热点(箭头的顶点或十字中心)。name 光标的描述,用来支持特殊的访问环境。
  7. java.awt.Component 1.0
    • public void setCursor(Cursor cursor) 1.1
      用光标图像设置给定光标。

8.4 AWT事件继承层次

  1. Java事件处理采用的是面向对象方法,所有的事件都是由java.util包中的EventObject类扩展而来的。EventObject类有一个子类AWTEvent,它是所有AWT事件类的父类。有些Swing组件将生成其他事件类型的事件对象;它们都直接扩展于EventObject,而不是AWTEvent。事件对象封装了事件源与监听器彼此通信的事件信息。在必要的时候,可以对传递给监听器对象的事件对象进行分析。
  2. AWT将事件分为低级(low-level)事件和语义(semantic)事件。语义事件是表示用户动作的事件,因此,ActionEvent是一种语义事件。低级事件是形成那些事件的事件。
  3. java.awt.event包中最常用的语义事件类:
    • ActionEvent(对应按钮点击、菜单选择、选择列表项或文本框中ENTER);
    • AdjustmentEvent(用户调节滚动条);
    • ItemEvent(用户从复选框或列表框中选择一项)。
  4. 常用的5个低级事件类是:
    • KeyEvent(一个键被按下或释放);
    • MouseEvent(鼠标键被按下、释放、移动或拖动);
    • MouseWheelEvent(鼠标滚轮被转动);
    • FocusEvent(某个组件获得焦点或失去焦点)。
    • WindowEvent(窗口状态被改变)。
      下列接口将监听这些事件:ActionListener、AdjustmentListener、FocusListener、ItemListener、KeyListener、MouseListener、MouseMotionListener、MouseWheelListener、WindowListener、WindowFocusListener、WindowStateListener。
  5. 常用的适配器类:FocusAdapter、KeyAdapter、MouseAdapter、MouseMotionAdapter、WindowAdapter。
  6. 事件处理总结
    接口 方法 参数/访问方法 事件源
    ActionListener actionPerformed ActionEvent(getActionCommand、getModifiers) AbstractButton、JComboBox、JTextField、Timer
    AdjustmentListener adjustmentValueChanged AdjustmentEvent(getAdjustable、getAdjustmentType、getValue) JScrollbar
    ItemListener itemStateChanged ItemEvent(getItem、getItemSelectale、getStateChange) AbstractButton、JComboBox
    FocusListener FocusGained、FocusLayout FocusEvent(isTemporary) Component
    KeyListener keyPressed、keyReleased、KeyTyped KeyEvent(getKeyChar、getKeyCode、getKeyModifiersText、getKeyText、isActionKey) Component
    MouseListener mousePressed、mouseReleased、mouseEntered、mouseExited、mouseClicked MouseEvent(getClickCount、getX、getY、getPoint、translatePoint) Component
    MouseMotionListener mouseDragged、mouseMoved MouseEvent Component
    MouseWheelListener mouseWheelMoved MouseWheelEvent(getWheelRotation、getScrollAmount) Component
    WindowListener windowClosing、windowOpened、windowIconified、windowDeiconified、windowClosed、windowActivated、windowDeactivated WindowEvent(getWindow) Window
    WindowFocusListener windowGainedFocus、windowLostFocus WindowEvent(getOppsiteWindow) Window
    WindowStateListener windowStateChanged WindowEvent(getOldState、getNewState) Winow

Java核心技术卷一基础知识-第8章-事件处理-读书笔记的更多相关文章

  1. Java核心技术卷一基础知识-第14章-多线程-读书笔记

    第 14 章 多线程 本章内容: * 什么是线程 * 中断线程 * 线程状态 * 线程属性 * 同步 * 阻塞队列 * 线程安全的集合 * Collable与Future * 执行器 * 同步器 * ...

  2. Java核心技术卷一基础知识-第5章-继承-读书笔记

    第5章 继承 本章内容: * 类.超类和子类 * Object:所有类的超类 * 泛型数组列表 * 对象包装器和自动装箱 * 参数数量可变的方法 * 枚举类 * 反射 * 继承设计的技巧 利用继承,人 ...

  3. Java核心技术卷一基础技术-第13章-集合-读书笔记

    第13章 集合 本章内容: * 集合接口 * 具体的集合 * 集合框架 * 算法 * 遗留的集合 13.1 集合接口 Enumeration接口提供了一种用于访问任意容器中各个元素的抽象机制. 13. ...

  4. Java核心技术卷一基础知识-第11章-异常、断言、日志和调试-读书笔记

    第11章 异常.断言.日志和调试 本章内容: * 处理错误 * 捕获异常 * 使用异常机制的技巧 * 使用断言 * 日志 * 调试技巧 * GUI程序排错技巧 * 使用调试器 11.1 处理错误 如果 ...

  5. Java核心技术卷一基础知识-第12章-泛型程序设计-读书笔记

    第12章 泛型程序设计 本章内容: * 为什么要使用泛型程序设计 * 定义简单泛型类 * 泛型方法 * 类型变量的限定 * 泛型代码和虚拟机 * 约束与局限性 * 泛型类型的继承规则 * 通配符类型 ...

  6. Java核心技术卷一基础知识-第9章-Swing用户界面组件-读书笔记

    第9章 Swing用户界面组件 本章内容: * Swing与模型-视图-控制器设计模式 * 布局管理概述 * 文本输入 * 选择组件 * 菜单 * 复杂的布局管理 * 对话框 本章将介绍构造功能更加齐 ...

  7. Java核心技术卷一基础知识-第10章-部署应用程序和applet-读书笔记

    第10章 部署应用程序和applet 本章内容: * JAR文件 * Java Web Start * applet * 应用程序首选项存储 10.1 JAR文件 一个JAR文件既可以包含类文件,也可 ...

  8. Java核心技术卷一基础知识-第7章-图形程序设计-读书笔记

    第7章 图形程序设计 本章内容: * Swing概述 * 创建框架 * 框架定位 * 在组件中显示信息 * 处理2D图形 * 使用颜色 * 文本使用特殊字体 * 显示图像 本章主要讲述如何编写定义屏幕 ...

  9. Java核心技术卷一基础知识-第6章-接口与内部类-读书笔记

    第6章 接口与内部类 本章内容: * 接口 * 对象克隆 * 接口与回调 * 内部类 * 代理 接口技术主要用来描述类具有什么功能,而并不给出每个功能的具体实现.一个类可以实现(implement)一 ...

随机推荐

  1. 使用Jmeter连接数据库检查数据库记录的方法

    一.首先下载Jdbc驱动(jdbc驱动分两种,classes与ojdbc文件,该用哪个需要检查电脑安装的jdk版本(查看方法cmd命令java –version) 关于各种版本的说明:http://e ...

  2. MySQL联接查询算法(NLJ、BNL、BKA、HashJoin)

    一.联接过程介绍 为了后面一些测试案例,我们事先创建了两张表,表数据如下:   1 2 3 4 CREATE TABLE t1 (m1 int, n1 char(1)); CREATE TABLE t ...

  3. 关于TCP窗口大小

    窗口字段 TCP Window字段用于接收端通知发送端:接收端当前能够接收的字节数(即当前允许发送端发送的字节数).在TCP Header中占有16bit长度,如下所示 0 1 2 3 0 1 2 3 ...

  4. mvc @html.action() 跨area调用controller 中的action

    @{Html.RenderAction("ActionName", "ControllerName", new { area = "Manager&q ...

  5. 快速排序的两种实现方法(js)

    快速排序的基本思想:通过一趟排序,将待排记录分割成独立的两部分,其中一部分记录的关键字均比另外一部分记录的关键字小,则可分别对着两部分记录继续进行排序,以达到整个序列有序的目的.----------- ...

  6. Sublime Text Snippets(代码片段)功能

    原文链接:http://www.bluesdream.com/blog/sublime-text-snippets-function.html 我们在编写代码的时候,总会遇到一些需要反复使用的代码片段 ...

  7. short s=1;s=s+1;short s=1;s+=1;有什么区别?

    short s = 1; s = s + 1; 这个编译一定是不通过的,会提示损失精度. short s = 1; s += 1: 这个编译反而可以通过. 隐式类型转换可以由小到大自动转,即byte ...

  8. Python3.7 Scrapy crawl 运行出错解决方法

    安装的是Python3.7,装上依赖包和scrapy后运行爬虫命令出错 File "D:\Python37\lib\site-packages\scrapy\extensions\telne ...

  9. 解决 ERROR: missing Change-Id in commit message footer 问题

    提交代码操作 git push origin HEAD:refs/for/XXX,提示失败ERROR: missing Change-Id in commit message footer,丢失Cha ...

  10. PackageManagerService 学习记录 基于7.1.1源码

    参考: http://blog.csdn.net/innost/article/details/47253179 http://blog.csdn.net/gaugamela/article/deta ...