概述
Java的事件监听是Java事件机制的实现,以Java Swing的事件机制为例,分析一下事件监听的各个组成部分以及功能:
Java事件机制的三个基本组成成分
- 事件对象
通常继承自java.util.EventObject的对象,一般可以用来判断事件类型的作用 - 事件源
触发事件的源头,在GUI和Swing编程中,如Button按钮等对象就是一个事件源 - 事件监听器
负责监听事件源发出的事件并作出响应动作的对象,通常实现java.util.EventListener接口
事件的一般流程
- 事件源注册监听器
- 事件发生,事件源向监听器发送事件对象
- 监听器对象响应事件
例程
下面用Demo来介绍事件机制的实现原理
事件对象类
1 | import java.util.EventObject; |
在该事件对象类中,除了默认继承自java.util.EventObject的source(即事件源对象属性)之外,
另外添加了一个eventType(事件类型属性),用来代表事件的类型。
当事件发生后,事件监听器的响应方法会接受到事件对象(作为方法参数被传递),
事件对象中的事件源属性可以提供数据源对象供响应方法调用,从而改变事件源的属性等。
事件源类
1 | import java.util.HashSet; |
事件源是事件触发的地方,其中有一个事件监听器集合,通过addEventListener方法可以
添加事件监听器到监听器集合中,也就是经常说的“注册事件监听器”。
其中的doOnAction方法是必不可少的一个操作,即在事件发生之后遍历监听器集合,
执行监听器定义的动作响应方法。
event1,event2,event3是定义的三个事件方法,模拟事件的发生,发生事件之后
程序需要实例化事件对象(事件对象储存了事件源即本对象的引用),并将其作为参数
依次调用每个监听器的动作响应方法,即上面的步骤。
事件监听器类
1 | import java.util.EventListener; |
事件监听器是一个接口,里面定义了一个固定名字的响应方法,用来提供给事件源调用。
注册事件监听器就是实现监听器接口的响应方法并添加到事件源的监听器集合中。
其中,事件对象继承自java.util.EventObject ,源码如下1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53package java.util;
/**
* <p>
* The root class from which all event state objects shall be derived.
* <p>
* All Events are constructed with a reference to the object, the "source",
* that is logically deemed to be the object upon which the Event in question
* initially occurred upon.
*
* @since JDK1.1
*/
public class EventObject implements java.io.Serializable {
private static final long serialVersionUID = 5516075349620653480L;
/**
* The object on which the Event initially occurred.
*/
protected transient Object source;
/**
* Constructs a prototypical Event.
*
* @param source The object on which the Event initially occurred.
* @exception IllegalArgumentException if source is null.
*/
public EventObject(Object source) {
if (source == null)
throw new IllegalArgumentException("null source");
this.source = source;
}
/**
* The object on which the Event initially occurred.
*
* @return The object on which the Event initially occurred.
*/
public Object getSource() {
return source;
}
/**
* Returns a String representation of this EventObject.
*
* @return A a String representation of this EventObject.
*/
public String toString() {
return getClass().getName() + "[source=" + source + "]";
}
}
事件监听类实现java.util.EventListener 接口,源码如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40package java.util;
/**
* A tagging interface that all event listener interfaces must extend.
* @since JDK1.1
*/
public interface EventListener {
}
定义好了事件监听Demo之后就可以测试使用了,下面根据这个Demo来实现几种事件监听的实现方式:
1.自身类作为事件监听器 :
import event.JohnsonEventListener;
import event.JohnsonEventObject;
import event.JohnsonEventSource;
/**
* 自身类作为事件监听器
*
* @Author Xuyh created at 2016年12月11日 下午5:57:46
*
*/
public class TestMain implements JohnsonEventListener {
public void onAction(JohnsonEventObject eventObject) {
JohnsonEventSource source = (JohnsonEventSource) eventObject.getSource();
source.sourceFunction("事件监听器 监听到事件--事件类型: " + String.valueOf(eventObject.getEventType()));
}
public static void main(String[] args) {
JohnsonEventSource source = new JohnsonEventSource();
source.addEventListener(new TestMain());
source.event1();
source.event2();
source.event3();
}
}
外部类作为事件监听器 :
监听器:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43package xuyihao;
import event.JohnsonEventListener;
import event.JohnsonEventObject;
import event.JohnsonEventSource;
/**
* 外部类作为事件监听器的外部类
*
* @Author Xuyh created at 2016年12月11日 下午6:02:46
*
*/
public class OuterListerner implements JohnsonEventListener {
public void onAction(JohnsonEventObject eventObject) {
JohnsonEventSource source = (JohnsonEventSource) eventObject.getSource();
source.sourceFunction("事件监听器 监听到事件--事件类型: " + String.valueOf(eventObject.getEventType()));
}
}
/**
*
*
* @Author Xuyh created at 2016年12月11日 下午6:02:46
*
*/
public class JohnsonMain {
public static void main(String args[]) {
exentTest();
}
/**
* 外部类作为事件监听器
*/
public static void exentTest() {
JohnsonEventSource source = new JohnsonEventSource();
source.addEventListener(new OuterListerner());
source.event1();
source.event2();
source.event3();
}
}
匿名内部类作为事件监听器 :
1 | import event.JohnsonEventListener; |
内部类作为事件监听器:
1 | import event.JohnsonEventListener; |