第9章AWT事件模型 本模块讨论了事件驱动的图形用户界面(GUD的用户输入机制。 The J uage Basics G出 in& smed asad and Ty Artas Ex ception Handling Developing Graphical User Inte rfaces Evnt ]ode1 Netcon玄 第一节相关问题 讨论一以下为与本模块内容有关的问题 哪些部分对于一个图形用户界面来说是必需的? 个图形化程序如何处理鼠标点击或者其他类型的用户交互? 第二节目标 完成本模块之后,你应当能够: 编写代码来处理在图形用户界面中发生的事件 描述 Adapter类的概念,包括如何和何时使用它们 根据事件对象的细节来确定产生事件的用户动作 为各种类型的事件创建合适的接口和事件处理器 第三节什么是事件? 什么是事件? 事件一描述发生了什么的对象 事件源一事件的产生器 事件处理器一接收事件、解释事件并处理用户交互的方法 如果用户在用户界面层执行了一个动作(鼠标点击和按键),这将导致一个事件的发生。事件是描述发生了什么的对象 存在各种不同类型的事件类用来描述各种类型的用户交互
104 第9章 AWT 事件模型 本模块讨论了事件驱动的图形用户界面(GUI)的用户输入机制。 第一节 相关问题 讨论 - 以下为与本模块内容有关的问题: - 哪些部分对于一个图形用户界面来说是必需的? - 一个图形化程序如何处理鼠标点击或者其他类型的用户交互? 第二节 目 标 完成本模块之后,你应当能够: - 编写代码来处理在图形用户界面中发生的事件 - 描述 Adapter 类的概念,包括如何和何时使用它们 - 根据事件对象的细节来确定产生事件的用户动作 - 为各种类型的事件创建合适的接口和事件处理器。 第三节 什么是事件? 如果用户在用户界面层执行了一个动作(鼠标点击和按键),这将导致一个事件的发生。事件是描述发生了什么的对象。 存在各种不同类型的事件类用来描述各种类型的用户交互。 什么是事件? - 事件-描述发生了什么的对象 - 事件源-事件的产生器 - 事件处理器-接收事件、解释事件并处理用户交互的方法
93.1事件源 事件源是一个事件的产生者。例如,在Butn组件上点击鼠标会产生以这个 Button为源的一个 Action event这个 Action Event实例是一个对象,它包含关于刚才所发生的那个事件的信息的对象。这些信息包括 etAction Command一返回与动作相关联的命令名称。 Getmodifiers一返回在执行动作时持有的修饰符 932事件处理器 事件处理器就是一个接收事件、解释事件并处理用户交互的方法 第四节JDK1.0的事件模型与JDKL.2的事件模型比较 JDK1.0的事件模型与JDK1,2的事件模型比较 次模型(JDK10) 委托模型(JDK12) 在JDK1.1中,事件接收和处理的方法发生了重要的改变。本节将比较以前的事件模型(JDK10)和当前的事件模型 (JDK1.1和JDK1.2)。 JDK1.0采用的是层次事件模型,而JDK11以及更高的版本采用的是委托事件模型。 941层次模型(JDK1.0) 层次模型是基于容器的。事件先发送到组件,然后沿容器层次向上传播。没有被组件处理的事件会自动地继续传播 到组件的容器 JDK1.0的事件模型与JDK1.2的事件模型比较 例如,在下图中,Buon对象(包含在一个 Frame上的Pane中)上的鼠标点击首先向 Button发送一个动作事件。如果 它没有被 Button处理,这个事件会被送往Pane,如果它在那儿仍然没有被处理,这个事件会被送往 frame 层次模型(JDK1.0) 优点 简单,而且非常适合面向对象的编程环境。 缺 事件只能由产生这个事件的组件或包含这个组件的容器处理。 -为了处理事件,你必须定义接收这个事件的组件的子类,或者在基 容器创建 handle Evento方法。 Frame lane Button Action event
105 9.3.1 事件源 事件源是一个事件的产生者。例如,在 Button 组件上点击鼠标会产生以这个 Button 为源的一个 ActionEvent. 这个 ActionEvent 实例是一个对象,它包含关于刚才所发生的那个事件的信息的对象。这些信息包括: - getActionCommand-返回与动作相关联的命令名称。 - GetModifiers-返回在执行动作时持有的修饰符。 9.3.2 事件处理器 事件处理器就是一个接收事件、解释事件并处理用户交互的方法。 第四节 JDK1.0 的事件模型与 JDK1.2 的事件模型比较 在 JDK1.1 中,事件接收和处理的方法发生了重要的改变。本节将比较以前的事件模型(JDK1.0)和当前的事件模型 (JDK1.1 和 JDK1.2)。 JDK1.0 采用的是层次事件模型,而 JDK1.1 以及更高的版本采用的是委托事件模型。 9.4.1 层次模型(JDK1.0) 层次模型是基于容器的。 事件先发送到组件,然后沿容器层次向上传播。没有被组件处理的事件会自动地继续传播 到组件的容器。 JDK1.0 的事件模型与 JDK1.2 的事件模型比较 例如,在下图中,Button 对象(包含在一个 Frame 上的 Panel 中)上的鼠标点击首先向 Button 发送一个动作事件。如果 它没有被 Button 处理,这个事件会被送往 Panel,如果它在那儿仍然没有被处理,这个事件会被送往 Frame。 JDK1.0 的事件模型与 JDK1.2 的事件模型比较 - 层次模型(JDK 1.0) - 委托模型(JDK 1.2) 层次模型(JDK1.0) 优点 - 简单,而且非常适合面向对象的编程环境。 缺点 - 事件只能由产生这个事件的组件或包含这个组件的容器处理。 - 为了处理事件,你必须定义接收这个事件的组件的子类,或者在基 容器创建 handleEvent()方法
层次模型(JDK1.0)(续) 这种模型有一个显著的优点: 它简单,而且非常适合面向对象的编程环境:说到底,所有的组件都继承了javaawt.componenT类,而handleevent 就在 java. awt. Component类中。 然而,这种模型也存在缺点: 事件只能由产生这个事件的组件或包含这个组件的容器处理。这个限制违反了面向对象编程的一个基本原则 功能应该包含在最合适的类中。而最适合处理事件的类往往并不是源组件的容器层次中的成员。 大量的CPU周期浪费在处理不相关的事件上。任何对于程序来说不相关或者并不重要的事件会沿容器层次一路 传播,直到最后被抛弃。不存在一种简单的方法来过滤事件。 为了处理事件,你必须定义接收这个事件的组件的子类,或者在基容器创建一个庞大的 handleevent0方法。 委托事件模型是在JDKL.1中引入的。在这个模型中,事件被送往产生这个事件的组件,然而,注册一个或多个称为 监听者的类取决于每一个组件,这些类包含事件处理器,用来接收和处理这个事件。采用这种方法,事件处理器可以安 排在与源组件分离的对象中。监听者就是实现了 Listener接口的类 Frame Panel and Frame event handlers Acton event ction handler actionPerformed (ActionEvent e)t 事件是只向注册的监听者报告的对象。每个事件都有一个对应的监听者接口,规定哪些方法必须在适合接收那种类 型的事件的类中定义。实现了定义那些方法的接口的类可以注册为一个监听者 942委托模型 从没有注册的监听者的组件中发出的事件不会被传播。 例如,这是一个只含有单个 Button的简单 Frame 1. import java. awt.* 4. public static void main(String args[]) i 6. Button b= new Button(Press Me!)i 10.f. setvisible(true)i Button handler类是一个处理器类,事件将被委托给这个类 3.public class ButtonHandler implements ActionListener 4. public void actionPerformed(ActionEvent e)t
106 层次模型(JDK1.0)(续) 这种模型有一个显著的优点: - 它简单,而且非常适合面向对象的编程环境;说到底,所有的组件都继承了 java.awt.Component类,而 handleEvent() 就在 java.awt.Component 类中。 然而,这种模型也存在缺点: - 事件只能由产生这个事件的组件或包含这个组件的容器处理。这个限制违反了面向对象编程的一个基本原则: 功能应该包含在最合适的类中。而最适合处理事件的类往往并不是源组件的容器层次中的成员。 - 大量的 CPU 周期浪费在处理不相关的事件上。任何对于程序来说不相关或者并不重要的事件会沿容器层次一路 传播,直到最后被抛弃。不存在一种简单的方法来过滤事件。 - 为了处理事件,你必须定义接收这个事件的组件的子类,或者在基容器创建一个庞大的 handleEvent()方法。 委托事件模型是在 JDK1.1 中引入的。在这个模型中,事件被送往产生这个事件的组件,然而,注册一个或多个称为 监听者的类取决于每一个组件,这些类包含事件处理器,用来接收和处理这个事件。采用这种方法,事件处理器可以安 排在与源组件分离的对象中。监听者就是实现了 Listener 接口的类。 事件是只向注册的监听者报告的对象。每个事件都有一个对应的监听者接口,规定哪些方法必须在适合接收那种类 型的事件的类中定义。实现了定义那些方法的接口的类可以注册为一个监听者。 9.4.2 委托模型 从没有注册的监听者的组件中发出的事件不会被传播。 例如,这是一个只含有单个 Button 的简单 Frame。 1.import java.awt.*; 2. 3.public class TestButton { 4.public static void main(String args[]) { 5.Frame f = new Frame("Test"); 6.Button b = new Button("Press Me!"); 7.b.addActionListener(new ButtonHandler()); 8.f.add(b,"Center"); 9.f.pack(); 10.f.setVisible(true); 11.} 12.} ButtonHandler 类是一个处理器类,事件将被委托给这个类。 1.import java.awt.event.*; 2. 3.public class ButtonHandler implements ActionListener { 4.public void actionPerformed(ActionEvent e) {
5. System. out. println("Action occurred") 6. System. out. println("Buttons label is 7+e. getActioncommand())i 这两个范例的特征如下 Bun类有一个 add Action Listner(ActionListener)方法 Addiction listner接口定义了一个方法 action Performed,用来接收一个 Action event 创建一个 Button对象时,这个对象可以通过使用 add Action Listener方法注册为 Action Events的监听者。调用这 个方法时带有一个实现了 Action Listener接口的类的参数 委托模型(JDK.或更高版本) 优点 事件不会被意外地处理 有可能创建并使用适配器( adapter)类对事件动作进行分类 委托模型有利于把工作分布到各个类中 缺点 不容易将JDK10代码移植到JDKl.1上 委托模型(JDK1.1或更高版本)(续) 在 Button对象上用鼠标进行点击时,将发送一个 Action event事件。这个 Action Event事件会被使用 ddActionListenerO方法进行注册的所有 ActionListener的 action Performed方法接收 Action event类的 getAction Commando方法返回与动作相关联的命令名称。以按钮的点击动作为例,将返回 Button 的标签。 这种方法有若干优点 事件不会被意外地处理。在层次模型中,一个事件可能传播到容器,并在非预期的层次被处理。 有可能创建并使用适配器( adapter)类对事件动作进行分类。 委托模型有利于把工作分布到各个类中。 新的事件模型提供对 Javabeans的支持。 这种方法也有一个缺点 尽管当前的JDK支持委托模型和JDK1.0事件模型,但不能混合使用JDκ1.0和JDKI. 第五节图形用户界面的行为 9.51事件类型 我们己经介绍了在单一类型事件上下文中从组件接收事件的通用机制。事件类的层次结构图如下所示。许多事件类 在 java. awt event包中,也有一些事件类在API的其他地方。 对于每类事件,都有一个接口,这个接口必须由想接收这个事件的类的对象实现。这个接口还要求定义一个或多个 方法。当发生特定的事件时,就会调用这些方法。表9-1列出了这些(事件)类型,并给出了每个类型对应的接口名称,以 ContainerEvent java. awt AWTEvent FocusEvent Com ponentevent InputEvent java beans. bean Context Bean contextEvent
107 5.System.out.println("Action occurred"); 6.System.out.println("Button's label is : ' 7.+ e.getActionCommand()); 8.} 9.} 这两个范例的特征如下: - Button 类有一个 addActionListner(ActionListener)方法。 - AddActionListner 接口定义了一个方法 actionPerformed,用来接收一个 ActionEvent。 - 创建一个 Button 对象时,这个对象可以通过使用 addActionListener 方法注册为 ActionEvents 的监听者。调用这 个方法时带有一个实现了 ActionListener 接口的类的参数。 委托模型(JDK1.1 或更高版本)(续) - 在 Button 对象上用 鼠标进行 点击时 ,将发送 一个 ActionEvent 事件 。这个 ActionEvent 事件会被 使用 addActionListener()方法进行注册的所有 ActionListener 的 actionPerformed()方法接收。 - ActionEvent类的 getActionCommand()方法返回与动作相关联的命令名称。以按钮的点击动作为例,将返回 Button 的标签。 这种方法有若干优点: - 事件不会被意外地处理。在层次模型中,一个事件可能传播到容器,并在非预期的层次被处理。 - 有可能创建并使用适配器(adapter)类对事件动作进行分类。 - 委托模型有利于把工作分布到各个类中。 - 新的事件模型提供对 JavaBeans 的支持。 这种方法也有一个缺点: - 尽管当前的 JDK 支持委托模型和 JDK1.0 事件模型,但不能混合使用 JDK1.0 和 JDK1.1。 第五节 图形用户界面的行为 9.5.1 事件类型 我们已经介绍了在单一类型事件上下文中从组件接收事件的通用机制。事件类的层次结构图如下所示。许多事件类 在 java.awt.event 包中,也有一些事件类在 API 的其他地方。 对于每类事件,都有一个接口,这个接口必须由想接收这个事件的类的对象实现。这个接口还要求定义一个或多个 方法。当发生特定的事件时,就会调用这些方法。表 9-1 列出了这些(事件)类型,并给出了每个类型对应的接口名称,以 委托模型(JDK1.1 或更高版本) 优点 - 事件不会被意外地处理。 - 有可能创建并使用适配器 (adapter)类对事件动作进行分类。 - 委托模型有利于把工作分布到各个类中。 缺点 - 不容易将 JDK1.0 代码移植到 JDK1.1 上
及所要求定义的方法。这些方法的名称是易于记忆的,名称表示了会引起这个方法被调用的源或条件 表9-1方法类型和接口 Category Interface Name Methods Action ActionListener actionPerformed (actionEvent) Mouse motion MouseMo tionlistener Mouse button Mouselistener mouseEntered(Mous eVent) mouseClicked(Mous eVent) KeyListener keyReleased( KeyEvent) ocus FocusListener focus Gained( Focus Event) focusLo st(Focusevent Adjustment AdjustmentListener ComponentListener componentMoved(ComponentEvent) componentHidden (ComponentEvent) component Shown(ComponentEvent) 表9-1方法类型和接口(续) Window Window listener window Closing( Window Event window iconified(window Event) indow closed( window Event) window Deactivated(window Event) Container ContainerListener componentAdded( ContainerEvent) componentRemoved( ContainerEvent TextLis tener textValue ChangedcTextEvent 9.52复杂的范例 本节将考察一个更复杂的Jawa软件范例。它将跟踪鼠标被按下时,鼠标的移动情况(鼠标拖动)。这个范例还将监测当 鼠标没有按下时,鼠标的移动情况(鼠标移动)。 当鼠标按下或没有按下时,移动鼠标产生的事件会被实现了 Mouse Motion listener接口的类的对象检取。这个接口要 求定义两个方法, mouse Dragged和 mouseMove(。即使你只对鼠标拖动感兴趣,也必须提供这两个方法。然而, mouseMove的体可以是空的 要检取其他鼠标事件,包括鼠标点击,必须定义 Mouselistener接口。这个接口包括若干个事件, mouseEntered
108 及所要求定义的方法。这些方法的名称是易于记忆的,名称表示了会引起这个方法被调用的源或条件。 表 9-1 方法类型和接口 Category Interface Name Methods Action ActionListener actionPerformed(ActionEvent) Item ItemListener itemStateChanged(ItemEvent) Mouse motion MouseMotionListener mouseDragged(MouseEvent) mouseMoved(MouseEvent) Mouse button MouseListener mousePressed(MouseEvent) mouseReleased(MouseEvent) mouseEntered(MouseEvent) mouseExited(MouseEvent) mouseClicked(MouseEvent) Key KeyListener keyPressed(KeyEvent) keyReleased(KeyEvent) keyTyped(KeyEvent) Focus FocusListener focusGained(FocusEvent) focusLost(FocusEvent) Adjustment AdjustmentListener adjustmentValueChanged (AdjustmentEvent) Component ComponentListener componentMoved(ComponentEvent) componentHidden(ComponentEvent) componentResized(ComponentEvent) componentShown(ComponentEvent) 表 9-1 方法类型和接口(续) 9.5.2 复杂的范例 本节将考察一个更复杂的 Java 软件范例。它将跟踪鼠标被按下时,鼠标的移动情况(鼠标拖动)。这个范例还将监测当 鼠标没有按下时,鼠标的移动情况(鼠标移动)。 当鼠标按下或没有按下时,移动鼠标产生的事件会被实现了 MouseMotionListener 接口的类的对象检取。这个接口要 求定义两个方法,mouseDragged()和 mouseMoved()。即使你只对鼠标拖动感兴趣,也必须提供这两个方法。然而, mouseMoved()的体可以是空的。 要检取其他鼠标事件,包括鼠标点击,必须定义 MouseListener 接口。这个接口包括若干个事件,即:mouseEntered
发生鼠标或键盘事件时,有关鼠标的位置和所按下的键的信息可以从事件中得到。代码如下 2. import java. awt event. 4. public class TwoListen implements 5. Mouse MotionListener, Mouselis tener 6.private Frame fi 7. private TextField tfi 9. public static void main(String args[l) 10. TwOListen two new TwoListen()i 11.two.9o(); 12.} 复杂的范例(续) 2.f new Frame("Two listeners example")i 4. BorderLayout. NORTH")i 6.f. add (tf," BorderLayout. SOUTH"); 8. f. addMouse MotionListener(this 1l.f. setvisible(true)i 12.} 14.// These are MouseMotionListener event 15.public id mouseDragged (MouseEvent e)( 16. string s= 17."Mouse dragging: x="+egetx()+ 18."Y="+e.getY(); 19. tf setText (s); 22. public void mouseMoved (Mous eVent e)( 25.// These are Mouselistener e vents 26. public void mouseClicked (MouseEvent e)t 29. public void mouseEntered (MouseEvent e)i 30.String s ="The mouse entered
109 mouseExited, mousePressed, mouseReleased 和 mouseClicked。 发生鼠标或键盘事件时,有关鼠标的位置和所按下的键的信息可以从事件中得到。代码如下: 1.import java.awt.*; 2.import java.awt.event.*; 3. 4.public class TwoListen implements 5.MouseMotionListener, MouseListener { 6.private Frame f; 7.private TextField tf; 8. 9.public static void main(String args[]) { 10.TwoListen two = new TwoListen(); 11.two.go(); 12.} 13. 复杂的范例(续) 1.public void go() { 2.f = new Frame("Two listeners example"); 3.f.add (new Label ("Click and drag the mouse"), 4."BorderLayout.NORTH"); 5.tf = new TextField (30); 6.f.add (tf, "BorderLayout.SOUTH"); 7. 8.f.addMouseMotionListener(this); 9.f.addMouseListener (this); 10.f.setSize(300, 200); 11.f.setVisible(true); 12.} 13. 14.// These are MouseMotionListener events 15.public void mouseDragged (MouseEvent e) { 16.String s = 17."Mouse dragging: X = " + e.getX() + 18." Y = " + e.getY(); 19.tf.setText (s); 20.} 21. 22.public void mouseMoved (MouseEvent e) { 23.} 24. 25.// These are MouseListener events 26.public void mouseClicked (MouseEvent e) { 27.} 28. 29.public void mouseEntered (MouseEvent e) { 30.String s = "The mouse entered";
31. tf setText (s) 32.} 复杂的范例(续) Exited (Mous eVent e) 2. String "The mouse has left the building"i 3. tf setText (s) 6.public void mousePressed (MouseEvent e) 9.public void mouseR leased (MouseEvent e)i 11.} 这个范例中的一些地方值得注意。它们将在以下的几节中讨论 定义多重接口 这个类由第4行中的如下代码声明: implements MouseMotionListener, MouseListener 声明多个接口时,可以用逗号隔开。 监听多个源 如果你在第11行和第12行中,调用如下方法 两种类型的事件都会引起 TwoListen类中的方法被调用。一个对象可以“监听”任意数量的事件源:它的类只需要实 现所要求的接口。 f. addMouseMotionListener(this)i 复杂的范例(续) 获取关于事件的细节 调用处理器方法(如 mouse Dragged时所带的事件参数可能会包含关于源事件的重要信息。为了确定可以获取关于某 类事件的哪些细节时,你应当查看 java. awt event包中合适的类文档 9.53多监听者 多监听者 多监听者可以使一个程序的不相关部分执行同样的动作。 事件发生时,所有被注册的监听者的处理器都会被调用 AWT事件监听框架事实上允许同一个组件带有多个监听者。一般地,如果你想写一个程序,它基于一个事件而执行 多个动作,把那些行为编写到处理器的方法里即可。然而,有时一个程序的设计要求同一程序的多个不相关的部分对于 同一事件作出反应。这种情况是有可能的,例如,将一个上下文敏感的帮助系统加到一个已存在的程序中 监听者机制允许你调用 addXXXlistener方法任意多次,而且,你可以根据你的设计需要指定仼意多个不同的监听者。 事件发生时,所有被注册的监听者的处理器都会被调用 注一没有定义调用事件处理器方法的顺序。通常,如果调用的顺序起作用,那么处理器就不是不相关的。在这种情况下, 只注册第一个监听者,并由它直接调用其它的监听者 954事件 Adapters(适配器)
110 31.tf.setText (s); 32.} 复杂的范例(续) 1.public void mouseExited (MouseEvent e) { 2.String s = "The mouse has left the building"; 3.tf.setText (s); 4.} 5. 6.public void mousePressed (MouseEvent e) { 7.} 8. 9.public void mouseReleased (MouseEvent e) { 10.} 11.} 这个范例中的一些地方值得注意。它们将在以下的几节中讨论。 定义多重接口 这个类由第 4 行中的如下代码声明: implements MouseMotionListener, MouseListener 声明多个接口时,可以用逗号隔开。 监听多个源 如果你在第 11 行和第 12 行中,调用如下方法: 两种类型的事件都会引起 TwoListen 类中的方法被调用。一个对象可以“监听”任意数量的事件源;它的类只需要实 现所要求的接口。 f.addMouseListener(this); f.addMouseMotionListener(this); 复杂的范例(续) 获取关于事件的细节 调用处理器方法(如 mouseDragged())时所带的事件参数可能会包含关于源事件的重要信息。为了确定可以获取关于某 类事件的哪些细节时,你应当查看 java.awt.event 包中合适的类文档。 9.5.3 多监听者 AWT 事件监听框架事实上允许同一个组件带有多个监听者。一般地,如果你想写一个程序,它基于一个事件而执行 多个动作,把那些行为编写到处理器的方法里即可。然而,有时一个程序的设计要求同一程序的多个不相关的部分对于 同一事件作出反应。这种情况是有可能的,例如,将一个上下文敏感的帮助系统加到一个已存在的程序中。 监听者机制允许你调用 addXXXlistener 方法任意多次,而且,你可以根据你的设计需要指定任意多个不同的监听者。 事件发生时,所有被注册的监听者的处理器都会被调用。 注-没有定义调用事件处理器方法的顺序。通常,如果调用的顺序起作用,那么处理器就不是不相关的。在这种情况下, 只注册第一个监听者,并由它直接调用其它的监听者。 9.5.4 事件 Adapters(适配器) 多监听者 - 多监听者可以使一个程序的不相关部分执行同样的动作。 - 事件发生时,所有被注册的监听者的处理器都会被调用
你定义的 Listener可以继承 Adapter类,而且只需重写你所需要的方法。例如: 现每个 Listener接口的所有方法的工作量是非常大的,尤其是 Mouselistener接口和 ComponentListener接口。 以 Mouselistener接口为例,它定义了如下方法 mouseClicked(Mous eVent mouseEntered(Mous eVent) mouseExited( Mouse Event mousePressed(Mous eVent mouseReleased (Mouseevent) 为了方便起见,Java语言提供了 Adapters类,用来实现含有多个方法的类。这些 Adapters类中的方法是空的。 可以继承 Adapters类,而且只需重写你所需要的方法。例如: 1. import java.awt.* 2. import java. awt. event. 4. public class MouseClickHandler extends Mouse Adapter t 6.//We just need the mous eClick handler, so we use 7.// the Adapter to avoid having to write all the 8.// event handler me thods 9.public void mouseClicked (MouseEvent e) 10.// Do something with the mouse click 12.} 9.55匿名类 可以在一个表达式的域中,包含整个类的定义。这种方法定义了一个所谓的匿名类并且立即创建了实例。匿名类通 常和AWT事件处理一起使用。例如 2.import java. awt event.* 3. public class AnonTest 4. private Fr ame f 5.private TextField tf. 7. public static void main( String args[1) 8. 9. AnonTest obj new AnonTest(i 10.ob] go(i 匿名类(续) 1. public void go()t 2. f new Frame("Anonymous classes example") 3. f. add(new Label(Click and drag the"+ 4."mouse", Border Layout. NORTH 5. tf new TextField (30) 6.f. add(tf, BorderLayout SoUTH);
111 你定义的 Listener 可以继承 Adapter 类,而且只需重写你所需要的方法。例如: 实现每个 Listener 接口的所有方法的工作量是非常大的,尤其是 MouseListener 接口和 ComponentListener 接口。 以 MouseListener 接口为例,它定义了如下方法: - mouseClicked(MouseEvent) - mouseEntered(MouseEvent) - mouseExited(MouseEvent) - mousePressed(MouseEvent) - mouseReleased(MouseEvent) 为了方便起见,Java 语言提供了 Adapters 类,用来实现含有多个方法的类。这些 Adapters 类中的方法是空的。 你可以继承 Adapters 类,而且只需重写你所需要的方法。例如: 1.import java.awt.*; 2.import java.awt.event.*; 3. 4.public class MouseClickHandler extends MouseAdapter { 5. 6.// We just need the mouseClick handler, so we use 7.// the Adapter to avoid having to write all the 8.// event handler methods 9.public void mouseClicked (MouseEvent e) { 10.// Do something with the mouse click... 11.} 12.} 9.5.5 匿名类 可以在一个表达式的域中,包含整个类的定义。这种方法定义了一个所谓的匿名类并且立即创建了实例。匿名类通 常和 AWT 事件处理一起使用。例如: 1.import java.awt.*; 2.import java.awt.event.*; 3.public class AnonTest { 4.private Frame f; 5.private TextField tf; 6. 7.public static void main(String args[]) 8.{ 9.AnonTest obj = new AnonTest(); 10.obj.go(); 11.} 12. 匿名类(续) 1.public void go() { 2.f = new Frame("Anonymous classes example"); 3.f.add(new Label("Click and drag the " + 4." mouse",BorderLayout.NORTH); 5.tf = new TextField (30); 6.f.add(tf,BorderLayout.SOUTH); 7
9. Mouse MotionAdapter() 10. public void mouseDragged (MouseEvent e)i 11. String s= 12."Mouse dragging: x +e getx()+ 13."Y +e getY( 14. tf setText (s)i 15.} 16.1);//<- note the closing parenthesis 18 f. addMouselistener (new Mous eclickHandler()) 19.f. setsize(300,200); 20.f. setvisible(true) 练习:事件 练习目标一你将编写、编译和运行包含事件处理器的 Calculator图形用户界面和 Account图形用户界面的修改版本。 准备 为了很好地完成这个练习,你必须对事件模型是如何工作的有一个清晰的了解。 任务 水平1:创建一个 Calculator图形用户界面,第二部分 1.使用你在模块8中创建的图形用户界面代码,编写一段事件代码,用来连接计算器的用户界面和处理计算 器上的函数的事件处理器 水平3:创建一个 Account图形用户界面,第二部分 1.创建一个 AccountEvent类,类的对象在帐目发生改变时被激活。然后激活送往 Bankmanager类的事件。根 据你在模块8中创建的 Teller java GUI代码为起点进行练习 三、练习小结 讨论一花几分钟时间讨论一下,在本实验练习过程中你都经历、提出和发现了什么 经验解释总结应用 四、检查一下你的进度 在进入下一个模块的学习之前,请确认你能够 编写代码来处理在图形用户界面中发生的事件 描述 Adapter类的概念,包括如何和何时使用它们 根据事件对象的细节来确定产生事件的用户动作 为各种类型的事件创建合适的接口和事件处理器。 五、思考 你现在已经知道如何为图形化输出和交互式用户输入来创建Java图形用户界面。然而,我们只介绍了能创建图形用 户界面的一些组件。其他的组件在图形用户界面中有什么用处呢?
112 8.f.addMouseMotionListener ( new 9.MouseMotionAdapter() { 10.public void mouseDragged (MouseEvent e) { 11.String s = 12."Mouse dragging: X = " + e.getX() + 13." Y = " + e.getY(); 14.tf.setText (s); 15.} 16.} ); // <- note the closing parenthesis 17. 18.f.addMouseListener (new MouseClickHandler()); 19.f.setSize(300, 200); 20.f.setVisible(true); 21.} 22.} 练习:事件 练习目标-你将编写、编译和运行包含事件处理器的 Calculator 图形用户界面 和 Account 图形用户界面的修改版本。 一、准备 为了很好地完成这个练习,你必须对事件模型是如何工作的有一个清晰的了解。 二、任务 水平 1:创建一个 Calculator 图形用户界面,第二部分 1. 使用你在模块 8 中创建的图形用户界面代码,编写一段事件代码,用来连接计算器的用户界面和处理计算 器上的函数的事件处理器。 水平 3:创建一个 Account 图形用户界面,第二部分 1. 创建一个 AccountEvent 类,类的对象在帐目发生改变时被激活。然后激活送往 Bankmanager 类的事件。根 据你在模块 8 中创建的 Teller.java GUI 代码为起点进行练习。 三、练习小结 讨论 - 花几分钟时间讨论一下,在本实验练习过程中你都经历、提出和发现了什么。 经验 解释 总结 应用 四、检查一下你的进度 在进入下一个模块的学习之前,请确认你能够: - 编写代码来处理在图形用户界面中发生的事件 - 描述 Adapter 类的概念,包括如何和何时使用它们 - 根据事件对象的细节来确定产生事件的用户动作 - 为各种类型的事件创建合适的接口和事件处理器。 五、思考 你现在已经知道如何为图形化输出和交互式用户输入来创建 Java 图形用户界面。然而,我们只介绍了能创建图形用 户界面的一些组件。其他的组件在图形用户界面中有什么用处呢?