• 沒有找到結果。

前面简要介绍了 AWT 提供的 GUI 组件和容器,但是,有了 GUI 组件还是无法构造一个 应用系统的用户界面,因为这样构造出的图形用户界面是无法与用户交互的,一个完整的用户 界面系统还必须具备事件处理能力。

那什么是事件呢?事件可以简单地认为是发生在应用程序上的用户的一个操作,当用户 和应用程序进行交互时,就需要用到事件。从 JDK 1.0 到 JDK 1.1,AWT 的事件处理机制有了 很大的变化,从 JDK 1.1 开始,AWT 采用了一种新的事件处理模型——代理事件模型。较 JDK 1.0 中的事件处理模型而言,新的事件处理模型不仅更为灵活,而且完全支持 JavaBeans。

但是,这里仍会先介绍 JDK 1.1 以前的事件处理机制,不仅仅因为这是后面的事件处理模型的 基础,而且仍有很多源码是用 JDK 1.1 以前的版本写的。

Java 中的事件主要有组件类事件共 6 大类,分别是:

(1)ComponentEvent

(2)ContainerEvent

(3)WindowEvent

(4)FocusEvent

(5)PaintEvent

(6)MouseEvent

它们均是当组件的状态发生变化时产生的动作类事件,Java 中的事件类都包含在 JDK 的 java.awt.event 包中。

4.7.1 Java中的事件体系结构

Java 中的事件体系结构如图 4.13 所示。

图 4.13 Java 中的事件体系结构图

AWT 的每个事件都包含若干个域,从事件域中可以获知这个事件的详细内容。常见事件 域如下:

1.id

事件类型,AWT 中定义了下述事件类型:

ACTION_EVENT:用户执行的某种动作。

GOT_FOCUS:获得焦点。

KEY_ACTION:按下功能键。

KEY_ACTION_RELEASE:释放功能键。

KEY_PRESS:按下标准键。

KEY_RELEASE:释放标准键。

LIST_DESELECT:不选列表的某项。

LIST_SELECT:选中列表中的某项。

LOAD_FILE:载入文件。

LOSE_FOCUS:失去焦点。

MOUSE_DOWN:按下鼠标键。

MOUSE_DRAG:拖动鼠标,modifiers 域的 Alt_MASK 给出了鼠标是否按下。

MOUSE_ENTER:鼠标进入组件。

MOUSE_EXIT:鼠标离开组件。

MOUSE _MOVE:鼠标移动,此时没有按下鼠标键。

MOUSE_UP:释放鼠标。

SAVE_FILE:保存文件。

SCROLL_ABSOLUTE:滚动条拖到某个位置。

SCROLL_LINE_DOWN:滚动条向下移一行。

SCROLL_LINE_UP:滚动条向上移一行。

SCROLL_PAGE_DOWN:滚动条向下移一页。

SCROLL_PAGE_UP:滚动条向上移一页。

WINDOW_DEICONIFY:窗口非图标化。

WINDOW_DESTROY:窗口销毁。

WINDOW_EXPOSE:窗口展开。

WINDOW_ICONIFY:窗口图标化。

WINDOW_MOVED:窗口移动。

2.target

事件的作用对象,即该事件是在哪个组件上发生的。

3.when

事件发生时间。

4.x.y

事件发生的位置。

5.key

键盘事件发生时键入的键值。

6.modifiers

事件发生时的功能键值,指 Alt、Ctrl、Shift 键的状态。

(1)Alt_MASK:按下了 Alt 键。

(2)Ctrl_MASK:按下了 Ctrl 键。

(3)Meta_MASK:在 UNIX 中按下了 Alt 键。

(4)Shift_MASK:按下了 Shift 键。

7.arg

事件的其他参数,根据不同的事件有所不同。

每个事件类都提供了相应的方法以便获得该事件的各种参数和状态。例如:ActionEvent 类提供下述成员方法:

(1)public String getActionCommand():获得该事件相关的命令字符串,例如按钮的标识 字符串。

(2)public int getModifiers():获得该事件发生时按下的功能键。

(3)public String paramString():获得表示该事件的参数字符串。

用户编程定义每个特定事件发生时程序应做出何种响应,这些响应代码会在对应的事件 发生时由系统自动调用。在 JDK 1.0 和以前的版本中,任何接受和处理事件的类都是 Component 类的子类,在图形用户界面中,容器中包含了组件或其他的容器,事件可能发生在某个组件中,

也可能发生在某个作为容器的窗口中。

当一个组件获得一个事件对象时,可忽略它,不做任何处理,这时返回 false,事件会继续 往上层传递,也可对该事件进行处理,处理时调用事件对象提供的方法获得参数进行处理,处 理完后,组件可以终止事件向上层传递。若事件处理结果返回 true,则表明终止事件向上传递。

4.7.2 Component类

Component 类中定义了一系列事件处理方法,这些方法的返回值均为 boolean 类型,用以 指明事件是否向上传递。

1.动作处理方法

用来捕捉处理在特定部件中产生的事件。当用户作用于某些组件(如按钮、选择框、菜 单项、滚动条等)时,产生的事件称为动作(action),AWT 把这类事件交由 action()方法处理。

public boolean action(Event evt, Object arg)

evt 参数给出当前事件实例,其中包含了时间的详细信息。arg 参数则是动作所作用的组 件,值与 evt.arg 相同。

2.键盘事件处理方法

(1)public boolean keyDown(Event evt, int key );

(2)public boolean keyUp(Event evt, int key);

其中 key 用来指明按下或释放的键的键值,与 evt.key 值相同。

3.鼠标事件处理方法

(1)按下鼠标键:public boolean mouseDown(Event evt,int x,int y)

(2)按下鼠标键拖动鼠标:public boolean mouseDrag(Event evt,int x,int y)

(3)鼠标进入 Applet:public boolean mouseEnter(Event evt,int x,int y)

(4)鼠标离开 Applet:public boolean mouseExit(Event evt,int x,int y)

(5)移动鼠标:public boolean mouseMove(Event evt,int x,int y)

(6)鼠标按钮被释放:public boolean mouseUp(Event evt,int x,int y)

传递给事件处理方法的有 3 个参数,即 evt、x 和 y。Event 是一个标识事件全部信息的类,

(x,y)是发生鼠标事件的坐标位置。与 evt.x 和 evt.y 相同。

4.通用事件处理方法

public boolean handleEvent(Event evt)

在类中重写的 action()、mouseUp()、keyUp()等方法实际上是被 handleEvent()方法简单地 调用,这个方法是组件的事件处理开关,鼠标、按键、动作等各种事件最先到 handleEvent() 方法中,被分流到各种简单的处理方法,如 mouseUp()。

如果对一个组件要重写其 handleEvent()方法,为了使所有基本事件(鼠标、键盘或动作事 件)都有机会被进行缺省处理,通常应在处理方法结束处调用父类的 handleEvent()方法。

下面的例子演示了如何接受鼠标事件 mouseDown 和键盘事件 keyDown。

【例 4.18】鼠标事件 mouseDown 和键盘事件 keyDown 应用示例。

//KeyEvent.java import java.applet.*;

import java.awt.*;

public class KeyEvent extends Applet {

private int posx,posy; //当前要写的字符的位置 private char[] manykeys; //记录键入字符的数组 private int keynumber; //记录键入字符的数目 public KeyEvent(){

}

public void init() { resize(320,240);

posx=10;

posy=10;

manykeys=new char[100];

keynumber=0;

}

public void desroy() { }

public void paint(Graphics g){

g.drawChars(manykeys,0,keynumber,posx,posy);

public boolean mouseDown(Event evt,int x,int y) {

//如果按下了鼠标,就在鼠标所单击处重新开始打字

return true;

}

public boolean mouseUp(Event evt,int x,int y) { return true;

}

//当按键是可显示字符时加入该字符并重绘窗口 public boolean keyDown(Event evt,int nKey) {

if(keynumber<100){

manykeys[keynumber]=(char)nKey;

keynumber++;

} repaint();

return true;

} }

4.7.3 代理事件模型

JDK 1.1 之后的代理事件模型中有 3 个角色:事件源、事件和事件监听器。事件处理三者 关系如图 4.14 所示。

图 4.14 代理事件模型

1.事件源

事件源是产生或发出事件的对象。例如,当单击了图形用户界面上的一个按钮后,按钮 就会产生一个鼠标按下的事件。此时,按钮就是事件源。前面提到,在 JDK 1.0 和以前的版本 中,任何接受和处理事件的类都是 Component 类的子类,但在 JDK 1.1 以后就不是这样了,任 何类都能接受和处理事件,接受之后,事件是由事件监听器来管理的。

2.事件

AWT 中定义了各种事件类,如鼠标事件(MouseEvent)和窗口事件(WindowEvent)等。

3.事件监听器

在 AWT 中,事件监听器是 java.awt.event 包中的一类接口,其中定义了当被监听的事件发 生时,需要调用的方法。事件监听器用于监听某类事件的发生,它通过调用事件源 add******

方法(******代表某类事件监听器),来登记所需监听的事件。当该事件源发出此类事件时,

事件监听器就会得到通知。

例如 KeyEvent 相对应的接口 KeyListener:

public interface KeyListener extends EventListener { public void keyPressed(KeyEvent ev);

public void keyReleased(KeyEvent ev);

public void keyTyped(KeyEvent ev);

}

AWT 的组件类中提供注册和注销监听器的方法。

注册监听器:

public void add<ListenerType>(<ListenerType>listener);

如:

button.addMouseListener(this);

注销监听器:

public void remove<ListenerType>(<ListenerType>listener);

如:

button.removeMouseListener(this);

下面是一些常用的事件监听器。

(1)ActionListener:Button、List、MenuItem、TextField 接收 Action_Event 事件。

(2)ItemListener:Choice、CheckBox 接收 Action_Event 事件,接收所有的 List_事件。

(3)FocusListener:接收 Got_Focus 和 Lost_Focus 事件。

(4)KeyListener:接收所有的 Key_事件。

(5)MouseMotionListener:接收 Mouse_Drag 和 Mouse_Move 事件。

(6)MouseListener:接收除了 Mouse_Drag 和 Mouse_Move 以外的所有 Mouse_事件。

(7)AdjustmentListener:接收所有的 Scroll_事件。

(8)WindowListener:接收所有的 Window_事件,除了 Window_Moved 事件。

(9)ComponentListener:接收 Window_Moved 事件。

有了以上的接口,就可以通过如下 3 个步骤来使用它们接收和管理事件。

(1)为类声明需要的事件监听器接口 和其他的接口声明方法一样。

例如:

public class AppletSample extends Applet implements ActionListener

如果该类中需要一个以上的事件监听器,则可以根据需要声明多个。

(2)为组件登记接口

在代码中,当生成一个组件作为事件源后,就需要为这个组件登记该类已经声明过的相 应的事件监听器,然后再加入该组件,所有的组件都有这样的登记方法,方法名的格式为:

add******,******是事件监听器的名字。

例如:

Button button1=new Button("OK");

button1.addActionListener(this);

add(button1);

这里 addActionListener 的参数为 this,表明当组件接收到 Action_Event 事件后,该类实现 的事件监视器接口就会自动处理这个事件。

(3)最后在类中实现接口声明的处理方法

比如 ActionListener 声明的事件处理方法为 actionPerformed(),在该类中就要实现这个 方法:

public void actionPerformed(ActionEvent event) { //填写所需代码

}

相關文件