Java —— 事件处理机制
一、Java事件主要角色
Source:事件源,即触发事件的对象;
EventObject:事件对象,即带有 EventSource 信息的事件对象,是对EventSource的包装;
Eventlistener:事件监听器,对该事件的处理。
说明:
1、Source:即任何具有行为的Java 对象,具有行为是为了能触发事件。
2、EventObject类:
继承关系:直接继承于Object ,实现了Serializable接口,是所有事件对象的父类(如界面编程中Action事件类的父类AWTEvent)。定义于java.util包。
EventObject提供了3个基本方法:
构造方法:EventObject(Object source)//source不能为null
普通方法:
Object getSource();//返回事件源
String toString();//返回该事件类名与事件源名
3、EventListener 接口:
继承关系:直接继承于Object,所有监听器的父接口。定义于java.util包。无方法。
二、Java 事件实现过程与触发过程
实现过程:
首先,为要触发事件的对象(source)定义事件对象;
其次,为事件对象定义事件监听器;
最后,定义事件源(source)的类,指定添加监听器的方法。
触发过程:
以按钮点击事件(属于Action事件)为例,首先我们通过继承于组件的addActionListener 方法,为按钮添加了ActionListener 接口实现类,那么按钮类中定义的与点击相关的某个方法A 就会把自身作为source创建一个事件对象,并将该事件对象传入addActionListener 方法所添加的监听器中,在监听器中根据source 类型或实例选择执行某段代码,如此便完成了事件的触发。
需要注意的是,组件(如JFram、Button等)触发Action 等事件时事件对象的创建是由JVM 自动完成的,而不是通过开发人员编码实现,即我们不关注Action 事件触发的细节,而是只关注 ActionListener 实现类中对业务的处理。
由此,可简单理解三个对象的作用为:
事件源(source):其一、规定事件由谁来产生;其二、在listener 中作路由;
事件对象(EventObject):起到传递事件信息的作用。是对source 的包装,根据不同的构造方式,可以附带除source外的其它信息;
事件监听器(EventListener):业务关注点。根据事件对象中的事件源(source)或事件对象类型进行路由选择,实现不同业务。
通过代码加深理解:
1、EventObject 构造函数解读:以ActionEvent 其中一个构造函数为例
public ActionEvent(Object source, int id, String command, int modifiers) {this(source, id, command, 0, modifiers);}
最终其实调用了另外一个构造函数,可以看出ActionEvent 中多了事件id、事件相关的字符串command(对输入框此值即是输入的值)、modifiers(代表事件期间是否按下shift, ctrl, alt, meta),此处0其实代表了一个long类型参数,代表修改时间。可见,ActionListener 在EventLIstener 基础上添加了除source 外的更多信息,可类比其他事件。
2、awt 或swing 界面编程中对事件的典型处理过程:以Button 的点击事件(属于ActionEvent)为例
首先,定义事件对象。此过程省略,java 自动实现了。
其次,定义监听器。如下:
class MyActionListener implements ActionListener{@Overridepublic void actionPerformed(ActionEvent e){//定义发生ActionEvent 事件时要执行什么。当然,一个监听器是可以监听多个事件源触发的ActionListener的,所以通常都会先判断事件源if(e.getSource() == myButtonOne){...}else if(e.getSource()==myButtonTwo{...}...}
}
说明:ActionEvent 不是我们自己定义的,所以不知道点击按钮时,按钮对象产生该ActionEvent 对象的细节,当然可读源码。如果是自己定义一些事件与事件源,则在事件源内部何时产生事件对象及怎样产生事件对象完全由我们自己定义。上面代码是通过==判断事件源的,这要求该类能直接访问到事件源对象。监听器的函数参数也有文章可做,可通过IoC的思想,传入实现监听器接口的不同类,通过类的不同来处理不同业务。
if(e instanceof MyEvent)//不关注事件源,而关注事件类型时,通过事件类型判断
if(e.getSource() instanceof MyEventSource)//类型已确定,关注事件来源时,通过事件源类型判断
最后,注册监听器。
JButton myButtonOne=new JButton("按钮一");
JButton myButtonTwo=new JButton("按钮二");
MyActionListener listener=new MyActionListener();
myButtonOne.addActionListener(listener);
myButtonTwo.addActionListener(listerner);
监听器理解:监听器本身就是实现了监听接口,所以其本质作用于接口相同,即将我们的关注的业务从事件源中抽离出来,便于管理。对于多个事件源的监听器,每次都只是根据事件源或事件类型执行了对应的那段代码。如果对addActionListener 后事件具体怎么产生的还是有疑问,那就看看第三点!
三、编写自己的事件模拟Java 事件处理
目的:了解事件是怎么自动触发的(事件源类是关键)。
代码:
/*** 事件类。参数source起路由作用,判断事件来源,作用相当于JSP* 的servlet。此处定义了两个事件源,实际第二个没用到,只是想说明可以通过注入接口或超类的思想将事件类别作为判断依据。*/
class EventClassOne extends EventObject{public EventClassOne(Object source) {/*选择执行哪中构造方式,此处只有EventObject(Object source)一种*/super(source);}
}
class EventClassTwo extends EventObject{public EventClassTwo(Object source) {super(source);}
}
/**事件源类。表明谁触发了事件,用于作为EventObject类的构造参数,在listener中作路由*/
class EventSource{private String who;Vector listeners=new Vector(); public EventSource(String who){this.who=who;}public String getActioner(){return who;}public void addMyEventListener(MyEventListener listener){listeners.add(listener);}/*设定say方法能被MyEventListener对象监听到*/public void say(String words){System.out.println(this.getActioner()+"说:"+words);for(int i=0;i<listeners.size();i++){MyEventListener listener=(MyEventListener) listeners.elementAt(i);/*发布事件。当然应该事先规划say方法事件能发布给哪些事件监听器。*/listener.onMyEvent(new EventClassOne(this));}}
}
/*** 自定义监听器中通过EventObject判断事件来源,所以前面说EventObject是起路由功能。*/
class MyEventListener implements EventListener{/*EventListener是与EventObject同级的最原始的监听器,当然里面什么方法都没有*/public void onMyEvent(EventObject e){/*如果该类与EventObject实例处于同一个类中,可以直接使用==判断事件来源*/if(e.getSource() instanceof EventSource){/*事件来源于OtherSource时要处理的业务*/EventSource tempSrc=(EventSource)e.getSource();System.out.println("收到来自"+tempSrc.getActioner()+"的事件!");}/*else if(e.getSource() instanceof OtherSource){System.out.println("事件来源于OtherSource时要处理的业务");}*/}
}
/*** 关键点:new几个事件,在awt、swing等界面编程中,ActionEvent事件(即行为)* 事件是java已经实现的,如点击鼠标事件,所以组件A只需使用addXxxListener方法* 添加监听器即可,运行时用户点击组件A,则自动使用A产生一个相应事件,并执行所有* listener的actionPerformed方法处理事件业务。*/
public class Main{public static MyEventListener listener = null;public static void main(String[] args){listener = new MyEventListener();EventSource 小白 = new EventSource("小白");小白.addMyEventListener(listener);小白.say("今天天气不错");小白.say("适合出去走走");}
}
运行结果:
特别说明:
instanceof 操作符能辨别子类,如上面代码中MyEventListener 中原来为:
if(e.getSource() instanceof EventSource)
改为下列通过类判断后同样能得到正确结果:
if(e instanceof EventClassOne)
四、Spring 中事件机制
原理都是一样的,见另外一篇日志:http://blog.csdn.net/qq_19865749/article/details/70186889
Java —— 事件处理机制相关推荐
- java事件处理模型_从零开始理解JAVA事件处理机制(3)
我们连续写了两小节的教师-学生的例子,必然觉得无聊死了,这样的例子我们就是玩上100遍,还是不知道该怎么写真实的代码.那从本节开始,我们开始往真实代码上面去靠拢. 事件最容易理解的例子是鼠标事件:我们 ...
- 从零开始理解JAVA事件处理机制(3)
我们连续写了两小节的教师-学生的例子,必然觉得无聊死了,这样的例子我们就是玩上100遍,还是不知道该怎么写真实的代码.那从本节开始,我们开始往真实代码上面去靠拢. 事件最容易理解的例子是鼠标事件:我们 ...
- java pc的录制与回放,用Java事件处理机制实现录制回放功能
下载本文示例代码 目前在一些java应用程序的GUI测试工具,可以提供捕获用户操作的能力并在代码被修改之后能够自动回放用户的操作.文章将分析Java的事件处理模型及其原理,介绍了基于事件源识别的捕获/ ...
- java事件处理机制---键盘事件
此案例实现了画框内圆形在按下 上下左右 时圆形的移动 事件源:产生事件的对象,如:键盘.鼠标等 事件:在事件源上产生了某种变化.如:键盘被按下等 键盘事件监听需要实现 implements KeyLi ...
- java事件处理机制(自定义事件)
java中的事件机制的参与者有3种角色: 1.event object:事件状态对象,用于listener的相应的方法之中,作为参数,一般存在与listerner的方法之中 2.event sourc ...
- java的actionlistener_「actionlistener」Java——事件处理机制监听者基础(一)动作监听ActionListener - seo实验室...
actionlistener 介绍: actionlistener是一个接口,ActionEvent通常在点击一个按钮或双击某个列表项或选中某个菜单时发生. 如何设置监听: 对监听者添加ActionL ...
- Java事件处理机制和适配器
最重要的是理解事件源,监视器,处理事件的接口的概念. 1.事件源:是能够产生时间的对象都可以叫事件源,比如文本框,按钮,下拉列表之类的组件. 2.监视器:事件源要产生事件,必须要有什么东西去监视它,以 ...
- java dispatchevent_java事件处理机制
java中的事件机制的参与者有3种角色: 1.event object:就是事件产生时具体的"事件",用于listener的相应的方法之中,作为参数,一般存在与listerner的 ...
- core java 8~9(GUI AWT事件处理机制)
MODULE 8 GUIs -------------------------------- GUI中的包: java.awt.*; javax.swing.*; java.awt.event.*; ...
最新文章
- 文件批量重命名的技术,你值得拥有
- mx3 android 5.1,魅族MX3揭晓:猎户座处理器5.1寸屏幕
- linux使用遇到的一些小问题
- 获取http请求标头_HTTP请求和标头参数的CDI拦截器–简单示例
- 初学者学习python2还是python3?
- js中的数组Array定义与sort方法使用示例
- RayMarching2:给球加上光照
- 内存降价-可以入手啦
- 项目心得--我的尺寸测量项目
- 发那可g10_浅谈FANUC系统G10指令
- C语言--简单除法运算
- OpenAI 开源语音识别模型 Whisper 初体验
- Autoware(Architecture Proposal)
- RGB颜色转换16进制
- 国内交互智能平板品类首创者希沃联手倍市得,进一步蓄力品牌发展势能
- 泛泰A900 刷4.4专用中文TWRP2.7.1.1版 支持自己主动识别手机版本号(全球首创)...
- 基于GEE平台提取水体
- python中for无限循环_关于循环:在Python中从1循环到无穷大
- java 方法实现数学黑洞
- Swift语言中的感叹号是什么意思?
热门文章
- 2018中国互联网安全大会9月举行!
- ITsMine在中国互联网安全大会(ISC)上被评为十大最具创新性的网络安全创业公司之一
- DPlayer微信浏览器不自动隐藏工具条
- 计算机旁边禁止放水英语怎么说,放水冲刷是什么意思
- DELL R720 新增内存条方法
- 1.《把时间当作朋友》——李笑来
- Apache HttpClient 5 笔记: SSL, Proxy 和 Multipart Upload
- 发表论文对保研有用吗
- macOS Monterey 12.5Beta1(21G5027d)官方dmg镜像
- 【NISP一级】4.3 移动终端安全