北京大学计算机系 代亚非

40
1 北北北北北北北北 北北北 北北北 北北北北

Upload: inara

Post on 16-Mar-2016

159 views

Category:

Documents


4 download

DESCRIPTION

北京大学计算机系 代亚非. 第三章 事件处理. 第 3 章 事件处理. 3.1 什么是事件 3.2 鼠标产生的事件 3.3 键盘产生的事件 3.4 动作事件 3.5 通用事件处理程序 3.6 发送自己的事件 3.7 Java 1.1 事件处理模型 3.9 小结. 外部程序 C 程序 数据库程序. form. cgi. www 浏览器. Web server. url. interact. applet. 3.1 什么是事件. CGI 之外的选择. 什么是事件 ? 用户用于交互而产生的键盘或 - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: 北京大学计算机系    代亚非

1

北京大学计算机系 代亚非

第三章 事件处理

Page 2: 北京大学计算机系    代亚非

2

第 3 章 事件处理3.1 什么是事件3.2 鼠标产生的事件3.3 键盘产生的事件3.4 动作事件3.5 通用事件处理程序3.6 发送自己的事件 3.7 Java 1.1 事件处理模型3.9 小结

Page 3: 北京大学计算机系    代亚非

3

• 什么是事件 ? 用户用于交互而产生的键盘或 鼠标动作 .• 响应用户的动作称为处理事件 .• 在类 Event 中 , 定义了所有的事件处理方法 , 小应用已经继承了这些方法 .

www 浏览器 Web server外部程序C 程序数据库程序

cgiform

applet

urlinteract

3.1 什么是事件CGI 之外的选择

Page 4: 北京大学计算机系    代亚非

4

3.1 什么是事件 import java.awt.Event;Event 在 java.awt 包中 , 无论哪个键按下或者释放 , 还是鼠标移动 , 按下鼠标或释放鼠标 ,AWT都会捕获 , 并产生一个事件 . 处理事件的核心是重写处理事件的方法通用方法 :   handEvent(Event evt, Object arg)专用方法 : MouseDown(Event evt, Object arg)

Page 5: 北京大学计算机系    代亚非

5

Event 类的数据域3.1 什么是事件

Event

Object arg

int clickCountint id int key

int modifiers Object target

int x int y long when

Page 6: 北京大学计算机系    代亚非

6

3.1 什么是事件

Event

HandleEvent()

MouseUp()

MouseDown()

MouseDrag()

MouseMove()

MouseEnter()

MouseExit()

keyDown()

KeyUp()

action()

如果你不覆盖你要处理的方法,则缺省的方法返回一个假值,通知系统没有处理事件 。

Page 7: 北京大学计算机系    代亚非

7

3.2 鼠标产生的事件鼠标事件的三个参数 :1. 事件的类型 ( 是移动 ? 托拽 )2. 是按下还是放开 ?3. 鼠标的位置 (x,y)方法的重写 : public boolean mouseDown(Event evt,int x,int y) {….}

Page 8: 北京大学计算机系    代亚非

8

捕获事件mouseDown

获得参数 (x,y)(Event evt, int x, int y)

在 (x,y) 处画叉paint() drawLine

3.2 鼠标产生的事件例 : 在鼠标单击的地方显示“ ” .(MouseClick.h

tml)

思路 : 记忆鼠标点过的所有点1.Point marks[]=newPoint[20];( 在 init 方法中 )2.marks[i++]=new Point(x,y); (MouseDown 方法中 )3. 将所有的点画出来 ( 在 paint 方法中 ) g.fillOval(x,y,10,10);

Page 9: 北京大学计算机系    代亚非

9

. 3.2 鼠标产生的事件

boolean mouseDown(Event evt, int x, int y){ Marks[i++]=new Point(x,y); repaint(); } public void paint(Graphics g){ int k; for (k=0;k<i;k++){ g.fillOval(Marks[k].x,Marks[k].y,10,10);}

import java.awt.*;import java.applet.*;public class mark extends Applet{ int i; Point Marks[];public void init(){Marks[] =new Point[20]; i=20;}

Page 10: 北京大学计算机系    代亚非

10

import java.awt.*;import java.applet.Applet;public class CountClick extends Applet{int CurrentMarks=0; public boolean mouseDown(Event evt,int x,int y) { CurrentMarks++; repaint(); return true; } public void paint(Graphics g) { g.drawString(" "+CurrentMarks,10,10);}}

3.2 鼠标产生的事件

[ 练习 ] 对鼠标的点击动作计数

Page 11: 北京大学计算机系    代亚非

11

捕获的方法 keyDown(Event evt, int key)Event 类的键常量 常量 键 常量 键 常量 键DOWN 下箭头键 END End 键 F1 F1 键 F2 F2 键 F3 F3 键 F4 F4 键 F5 F5 键 F6 F6 键 F7 F7 键 F8 F8 键 F9 F9 键 F10 F10 键 F11 F11 键 F12 F12 键 HOME Home 键 LEFT 左箭头键 PGDN PageDown 键 PGUP PageUp 键 RIGHT 右箭头键 UP 上箭头键

3.3 键盘产生的事件

Page 12: 北京大学计算机系    代亚非

12

例题 : 显示用户按下的字母键内容3.3 键盘产生的事件

import java.applet.Applet;import java.awt.*;{ char Presskey; public boolean keyDown(Event evt, int key) { Presskey=(char)key;

repaint(); return true;}

public void paint(Graphics g) { g.drawString(Presskey,10,10); }}

Page 13: 北京大学计算机系    代亚非

13

3.3 键盘产生的事件键盘事件处理通常包括 : 显示字符 , 光标移动特殊键 public boolean keyDown(Event evt, int key) { switch(key) { case Event.F1: {….}; case Event.PGUP: {…} } }修正键 if(evt.shiftDown()) if(evt.controlDown());

Page 14: 北京大学计算机系    代亚非

14

3.3 键盘产生的事件练习题 : 在屏幕上显示用户输入的字符串在前一题的基础上 , 将字符串起来 , 但是不能用 :String s; s=s+presskey;应该用 StringBuffer 对象的 append 方法StringBuffer sb; sb.appned(presskey); sb 的内容不能直接用 g.drawString()应该用 g.drawString(sb.toString(),x,y);

Page 15: 北京大学计算机系    代亚非

15

3.4 动作事件凡是由构件产生的事件叫动作事件 ACTION_EVENT, 处理这类事件的方法是 : action().

取消确定music

sports

art

Page 16: 北京大学计算机系    代亚非

16

3.4 动作事件action(Event evt, Object arg)evt.target: 指明事件类型 (button,checkbox,list,...)

Event

Object arg

int clickCountint id int key

int modifiers Object target

int x int y long when

Page 17: 北京大学计算机系    代亚非

17

3.4 动作事件判断组件类型 ( 如是 button 或 checkbox) if(evt.target instanceof Button) if(evt.target instanceof Checkbox)判断是哪多个同类组件中的哪一个 if(evt.target==button1) if(evt.target=button2)或者通过判断标签内容 if(arg==“ 确定” ) if(arg==“ 取消” )

Page 18: 北京大学计算机系    代亚非

18

3.4 动作事件例 : 记录按下按钮的次数 , 并显示出来 .import java.awt.*;import java.applet.Applet;public class CountClick extends Applet{ int CurrentMarks=0; public init() { Button b1=new Button(“ 按钮” ); add.b1; } public boolean action(Event evt,Object arg) { CurrentMarks++; repaint(); return true; } public void paint(Graphics g) { g.drawString(" "+CurrentMarks,10,10);}}

10

按钮

Page 19: 北京大学计算机系    代亚非

19

思路 :1. 设计两个按钮 ( 后面详细讲 )2. 事件处理 action 根据选择 , 分别标记园或方3 根据标记画出相应图形 g.drawCirlce(50,50,50,50); g.drawRect(25,25,75,75);

3.4 动作事件例 : 根据用户选择画图形

import java.awt.*;import java.applet.Applet;public class drawing extends Applet{ boolean circlemark=true; public init() { Button b1=new Button(“ 园” ); Button b2=new Button(“ 方” ); add.b1; add.b2; }

园 方

Page 20: 北京大学计算机系    代亚非

20

3.4 动作事件public void paint(Graphics g) { if (circlemark) g.filloval(10,10,30,30); else g.fillRect(20,20,40,40}; } public boolean action(Event evt,Object arg) { if (evt.target==b1) circlrmark=true; else circlrmark=false; repaint(); return true; }

Page 21: 北京大学计算机系    代亚非

21

handleEvent 处理所有的小应用程序所接受的事件 , 由它将事件送给相对应的方法 . 让我们看一下 handleEvent 的缺省实现

3.5 通用的事件处理程序 -----handleEvent

public boolean handleEvent(Event evt) { switch(evt) { case Event.MOUSE_ENTER: return mouseEnter(evt,evt.x,evt.y); case Event.MOUSE_EXIT: return mouseExit(evt,evt.x,evt.y); case Event.MOUSE_MOVE: return mouseMove(evt,evt.x,evt.y);

Page 22: 北京大学计算机系    代亚非

22

3.5 通用的事件处理程序 -----handleEvent case Event.MOUSE_DRAG: return mouseDrag(evt,evt.x,evt.y); case Event.MOUSE_UP: return mouseUp(evt,evt.x,evt.y); case Event.MOUSE_DOWN: return mouseDown(evt,evt.x,evt.y); case Event.KEY_PRESS: case Event.KEY_ACTION: return keyDown(evt,evt.key); case Event.KEY_RELEASE:

Page 23: 北京大学计算机系    代亚非

23

3.5 通用的事件处理程序 ---handleEvent case Event.KEY_ACTION_RELEASE: return keyUp(evt,evt.key); case Event.ACTION_EVENT: return action(evt,evt.arg); case Event.GOT_FOCUS: return gotFocus(evt,evt.arg); case Event.LOST_FOCUS: return lostFocus(evt,evt.arg); } return false;}

Page 24: 北京大学计算机系    代亚非

24

覆盖 handleEvent 的情况 ( 原来的 handleEvent 不被执行 ): 只处理我们感兴趣的事 :

public boolean handleEvent(Event evt) { switch(evt.id) { case Event.MOUSE_ENTER: //doing something; case Event.MOUSE_EXIT: //doing something; }}

3.5 通用的事件处理程序 ---handleEvent

return false;

default:return super.handelEvent(evt);

Page 25: 北京大学计算机系    代亚非

25.

3.7 Java1.1 事件模型Java 1.0 的事件管理机制在 Java1.0 中,多数事件发生在类 component 里,并通过 handleEvent() 方法将事件传递给相应的处理方法 ,如果没有这样的方法 , 则沿着包含层次传给上一级容器 ,直到最顶层容器仍没有处理 , 则合理遗弃 , 不适于重用 .

例如一个发生在按钮上的事件 , 处理它的 action 方法通常属于包含按钮的父类容器 , 这不符合面向对象的设计原则Java 1.1 的事件管理机制在 Java 1.1 中,一个事件常常被其它对象处理,这些对象称为事件监听器,当特定事件发生时,相应的监听器能够知道。 AWT 共有 11 个监听器类,每个都有处理事件的方法。

Page 26: 北京大学计算机系    代亚非

26

3.7 Java1.1 事件模型在 Java 1.1 中如何捕获事件 ?三个步骤 :1. 必须定义一个类来实现接口class ButtonTracker implements ActionListener{…}2. 定义方法3. 向构件注册该类的一个实例button1.addActionListener(this);checkbox.addActionListener(this);

Page 27: 北京大学计算机系    代亚非

27

3.7 Java1.1 事件模型Java1.0 和 Java1.1 事件模型的区别 ?在 Java1.1 中 , 事件不再沿着包含层次向上传递 ,而是传给一个监听器 , 因此在 Java1.1 中 , 你希望发生在构件事件由哪个监听器处理 , 就将该监听器注册到构件上 .

Page 28: 北京大学计算机系    代亚非

28

3.7 Java1.1 事件模型窗口

button

panel

按钮的监听器

窗口或面板的监听器

Page 29: 北京大学计算机系    代亚非

29

3.7 Java1.1 事件模型常用的监听器及其方法键盘监听器 :KeyListener, 方法 :keyPressed, KeyReleased, keyTyped.鼠标监听器 : MouseListener, 方法 :mouseClicked, mousePressed, mouseReleased, mouseEntered, mouseExited构件监听器 :ActionListener, 方法 :actionPerformed();如果一个监听器有若干各方法 , 则必须将这些方法全部覆盖

Page 30: 北京大学计算机系    代亚非

30

3.7 Java1.1 事件模型例 : import java.awt.event.*;import java.awt.*; import java.applet.*;public class TestButton extends Applet { Button button1; Color color;

}

Page 31: 北京大学计算机系    代亚非

31

3.7 Java1.1 事件模型public void init(){ button1 = new Button("Test Button"); button1.addActionListener (new ButtonHandler(this)); add(button1); Font font = new Font("TimesRoman", Font.PLAIN, 48); g.setFont(font); color = Color.black; resize(400, 200); }

Page 32: 北京大学计算机系    代亚非

32

3.7 Java1.1 事件模型public void paint(Graphics g){ g.setColor(color); g.drawString("TEST COLOR", 55, 120);}

Page 33: 北京大学计算机系    代亚非

33

3.7 Java1.1 事件模型public class ButtonHandler implements ActionListener{ TestButton a; ButtonHandler(TestButton tb) { a=ts;} public void actionPerformed(ActionEvent event) { String arg = event.getActionCommand(); if (arg == "Test Button") { if (a.color == Color.black) a.color = Color.red; else a.color = Color.black; a.repaint(); } }

Page 34: 北京大学计算机系    代亚非

34

3.7 Java1.1 事件模型class TestButton

color=black;paint()

class ButtonHandler a

a.color=black;

button

new ButtonHandler(this);

100101

100101

Page 35: 北京大学计算机系    代亚非

35

3.7 Java1.1 事件模型public class TestButtoninner extends Applet{ Button button1; Color color; Font font; class ButtonHandler implements ActionListener { public void actionPerformed(ActionEvent event) { String arg = event.getActionCommand(); if (arg == "Test Button") { if (color == Color.black) color = Color.red; else color = Color.black; repaint(); } } }

Page 36: 北京大学计算机系    代亚非

36

3.7 Java1.1 事件模型在某个类的内部定义的类叫内部类内部类的特点 :内部类可以访问外部类的数据和方法内部类的匿名形式是指 :在定义一个新类的同时创建一个实例 .

class Example {public void init() { Button button1=new Button(“button”); button1.addActionListener(new ButtonHandler() { public void actionPerformed(ActionEvent event) { String arg = event.getActionCommand(); if (arg == "Test Button") { if (color == Color.black) color = Color.red; else color = Color.black; repaint(); } };

.

Page 37: 北京大学计算机系    代亚非

37

3.7 Java1.1 事件模型适配器简化代码不用适配器时 , 必须对某个适配器的多个方法进行重写 ,加入适配器后可以为这些方法提空实现class MouseAdapter implements MousListener{ public void mouseClicked(MouseEvent e) {} public void mousePressed(MouseEvent e) {} public void mouseReleased(MouseEvent e) {} public void mouseEntered(MouseEvent e) {} public void mouseExited(MouseEvent e) {}}

Page 38: 北京大学计算机系    代亚非

38

3.7 Java1.1 事件模型继承某个适配器的子类 , 则程序中只需覆盖你需要的方法 , 其余方法则从父类继承class MouseTrack extends MouseAdapter { public void mouseClicked(MouseEvent e) { //…handle mouse click event; } }

Page 39: 北京大学计算机系    代亚非

39

事件由用户的使用了鼠标和键盘动作引起的事件由事件处理器来处理handleEvent() 方法是 Applet 从 component 继承而来的 .重写 handleEvent() 方法时注意返回 false 指明有些情况被忽略 , 将其传给上层对象 .在组件上产生的动作叫动作事件 ,action 方法类处理

3.8 小结

Page 40: 北京大学计算机系    代亚非

40

3.10 作业1. 在鼠标按下的两点之间画一条线