java添加事件监听器_Java事件监听器的四种实现方式

自身类作为事件监听器

外部类作为事件监听器

匿名内部类作为事件监听器

内部类作为事件监听器

自身类作为事件监听器:

1 import javax.swing.*;2 import java.awt.*;3 import java.awt.event.*;4

5 /**

6 *Java事件处理机制:自身类作为事件监听器7 *@authorWinty(wintys@gmail.com)8 *@version2008-12-39 */

10 class ThisClassEvent extends JFrame implementsActionListener{11 JButton btn;12

13 publicThisClassEvent(){14 super("Java事件监听机制");15 setLayout(newFlowLayout());16 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);17

18 btn=new JButton("点击");19 btn.addActionListener(this);20 getContentPane().add(btn);21

22 setBounds(200,200,300,160);23 setVisible(true);24 }25

26 /**************************************/

27 public voidactionPerformed (ActionEvent e){28 Container c=getContentPane();29 c.setBackground(Color.red);30 }31 /**************************************/

32

33 public static voidmain(String args[]){34 newThisClassEvent();35 }36 }

外部类作为事件监听器:

1 import java.awt.*;2 import java.awt.event.*;3 import javax.swing.*;4

5 /**

6 *Java事件处理机制:外部类作为事件监听器7 *@authorWinty(wintys@gmail.com)8 *@version2008-12-39 */

10 class OuterClassEvent extendsJFrame{11 JButton btn;12

13 publicOuterClassEvent(){14 super("Java事件监听机制");15 setLayout(newFlowLayout());16 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);17

18 btn=new JButton("点击");19 btn.addActionListener(new OuterClass(this));20 getContentPane().add(btn);21

22 setBounds(200,200,300,160);23 setVisible(true);24 }25

26 public static voidmain(String args[]){27 newOuterClassEvent();28 }29 }30

31 /*外部类*********************************/

32 class OuterClass implementsActionListener{33 OuterClassEvent oce;34

35 publicOuterClass(OuterClassEvent oce){36 this.oce =oce;37 }38

39 public voidactionPerformed(ActionEvent e){40 Container c=oce.getContentPane();41 c.setBackground(Color.red);42 }43 }

匿名内部类作为事件监听器:

import java.awt.*;import java.awt.event.*;import javax.swing.*;/***Java事件处理机制:匿名内部类作为事件监听器

*@authorWinty(wintys@gmail.com)

*@version2008-12-3*/

class AnonymousEvent extendsJFrame{

JButton btn;publicAnonymousEvent(){super("Java事件监听机制");

setLayout(newFlowLayout());

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

btn=new JButton("点击");/*匿名内部类******************************/btn.addActionListener(newActionListener(){public voidactionPerformed(ActionEvent e){

Container c=getContentPane();

c.setBackground(Color.red);

}

}

);/***************************************/getContentPane().add(btn);

setBounds(200,200,300,160);

setVisible(true);

}public static voidmain(String args[]){newAnonymousEvent();

}

}

内部类作为事件监听器:

import java.awt.*;import java.awt.event.*;import javax.swing.*;/***Java事件处理机制:内部类作为事件监听器

*@authorWinty(wintys@gmail.com)

*@version2008-12-3*/

class InnerClassEvent extendsJFrame{

JButton btn;publicInnerClassEvent(){super("Java事件监听机制");

setLayout(newFlowLayout());

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

btn=new JButton("点击");

btn.addActionListener(newInnerClass());

getContentPane().add(btn);

setBounds(200,200,300,160);

setVisible(true);

}/*内部类*********************************/

class InnerClass implementsActionListener{public voidactionPerformed (ActionEvent e){

Container c=getContentPane();

c.setBackground(Color.red);

}

}/**************************************/

public static voidmain(String args[]){newInnerClassEvent();

}

}

什么是监听器

监听器就是一个实现特定接口的普通java程序,这个程序专门用于监听另一个java对象的方法调用或属性改变,当被监听对象发生上述事件后,监听器某个方法将立即被执行。。

为什么我们要使用监听器?

监听器可以用来检测网站的在线人数,统计网站的访问量等等!

监听器组件

监听器涉及三个组件:事件源,事件对象,事件监听器

当事件源发生某个动作的时候,它会调用事件监听器的方法,并在调用事件监听器方法的时候把事件对象传递进去。

我们在监听器中就可以通过事件对象获取得到事件源,从而对事件源进行操作!

fa264ef8e2083da68859a6a547e087a1.png

模拟监听器

既然上面已经说了监听器的概念了,监听器涉及三个组件:事件源,事件对象,事件监听器。

我们就写一个对象,被监听器监听

监听器

监听器定义为接口,监听的方法需要事件对象传递进来,从而在监听器上通过事件对象获取得到事件源,对事件源进行修改!

/*** 事件监听器** 监听Person事件源的eat和sleep方法*/

interfacePersonListener{

voiddoEat(Event event);

voiddoSleep(Event event);

}

事件源

事件源是一个Person类,它有eat和sleep()方法。

事件源需要注册监听器(即在事件源上关联监听器对象)

如果触发了eat或sleep()方法的时候,会调用监听器的方法,并将事件对象传递进去

/**** 事件源Person** 事件源要提供方法注册监听器(即在事件源上关联监听器对象)*/

classPerson {

//在成员变量定义一个监听器对象

private PersonListener personListener ;

//在事件源中定义两个方法

publicvoidEat() {

//当事件源调用了Eat方法时,应该触发监听器的方法,调用监听器的方法并把事件对象传递进去

personListener.doEat(new Event(this));

}

publicvoidsleep() {

//当事件源调用了Eat方法时,应该触发监听器的方法,调用监听器的方法并把事件对象传递进去

personListener.doSleep(new Event(this));

}

//注册监听器,该类没有监听器对象啊,那么就传递进来吧。

publicvoidregisterLister(PersonListener personListener) {

this.personListener = personListener;

}

}

事件对象

事件对象封装了事件源。

监听器可以从事件对象上获取得到事件源的对象(信息)

/*** 事件对象Even** 事件对象封装了事件源** 在监听器上能够通过事件对象获取得到事件源***/

classEvent{

private Person person;

publicEvent() {

}

publicEvent(Person person) {

this.person = person;

}

publicPerson getResource() {

return person;

}

}

测试

publicstaticvoidmain(String[] args) {

Person person = new Person();

//注册监听器()

person.registerLister(new PersonListener() {

@Override

publicvoiddoEat(Event event) {

Person person1 = event.getResource();

System.out.println(person1 + "正在吃饭呢!");

}

@Override

publicvoiddoSleep(Event event) {

Person person1 = event.getResource();

System.out.println(person1 + "正在睡觉呢!");

}

});

//当调用eat方法时,触发事件,将事件对象传递给监听器,最后监听器获得事件源,对事件源进行操作

person.Eat();

}

7c532d2cfd35ecab1c58244e598c9505.png

事件源:拥有事件

监听器:监听事件源所拥有的事件(带事件对象参数的)

事件对象:事件对象封装了事件源对象

事件源要与监听器有关系,就得注册监听器【提供方法得到监听器对象】

触发事件源的事件,实际会提交给监听器对象处理,并且把事件对象传递过去给监听器。

Servlet监听器

在Servlet规范中定义了多种类型的监听器,它们用于监听的事件源分别 ServletContext, HttpSession和ServletRequest这三个域对象

和其它事件监听器略有不同的是,servlet监听器的注册不是直接注册在事件源上,而是由WEB容器负责注册,开发人员只需在web.xml文件中使用标签配置好监听器,

监听对象的创建和销毁

HttpSessionListener、ServletContextListener、ServletRequestListener分别监控着Session、Context、Request对象的创建和销毁

HttpSessionListener(可以用来收集在线者信息)

ServletContextListener(可以获取web.xml里面的参数配置)

ServletRequestListener

测试

public classListener1 implementsServletContextListener,

HttpSessionListener, ServletRequestListener {

// Public constructor is required by servlet spec

publicListener1() {

}

publicvoidcontextInitialized(ServletContextEvent sce) {

System.out.println("容器创建了");

}

publicvoidcontextDestroyed(ServletContextEvent sce) {

System.out.println("容器销毁了");

}

publicvoidsessionCreated(HttpSessionEvent se) {

System.out.println("Session创建了");

}

publicvoidsessionDestroyed(HttpSessionEvent se) {

System.out.println("Session销毁了");

}

@Override

publicvoidrequestDestroyed(ServletRequestEvent servletRequestEvent) {

}

@Override

publicvoidrequestInitialized(ServletRequestEvent servletRequestEvent) {

}

}

监听器监听到ServletContext的初始化了,Session的创建和ServletContext的销毁。(服务器停掉,不代表Session就被销毁了。Session的创建是在内存中的,所以没看到Session被销毁了)

73ea36b91f8087900564070fcb747be8.gif

监听对象属性变化

ServletContextAttributeListener、HttpSessionAttributeListener、ServletRequestAttributeListener分别监听着Context、Session、Request对象属性的变化

这三个接口中都定义了三个方法来处理被监听对象中的属性的增加,删除和替换的事件,同一个事件在这三个接口中对应的方法名称完全相同,只是接受的参数类型不同。

attributeAdded()

attributeRemoved()

attributeReplaced()

测试

这里我只演示Context对象,其他对象都是以此类推的,就不一一测试了。

实现ServletContextAttributeListener接口。

public classListener1 implementsServletContextAttributeListener {

@Override

publicvoidattributeAdded(ServletContextAttributeEvent servletContextAttributeEvent) {

System.out.println("Context对象增加了属性");

}

@Override

publicvoidattributeRemoved(ServletContextAttributeEvent servletContextAttributeEvent) {

System.out.println("Context对象删除了属性");

}

@Override

publicvoidattributeReplaced(ServletContextAttributeEvent servletContextAttributeEvent) {

System.out.println("Context对象替换了属性");

}

}

测试的Servlet

protectedvoiddoPost(HttpServletRequest request, HttpServletResponse response) throwsServletException, IOException {

ServletContext context = this.getServletContext();

context.setAttribute("aa", "123");

context.setAttribute("aa", "234");

context.removeAttribute("aa");

}

07993b2cc73af33852dbfec11ede1744.gif

监听Session内的对象

除了上面的6种Listener,还有两种Linstener监听Session内的对象,分别是HttpSessionBindingListener和HttpSessionActivationListener,实现这两个接口并不需要在web.xml文件中注册

实现HttpSessionBindingListener接口,JavaBean 对象可以感知自己被绑定到 Session 中和从 Session 中删除的事件【和HttpSessionAttributeListener的作用是差不多的】

实现HttpSessionActivationListener接口,JavaBean 对象可以感知自己被活化和钝化的事件(当服务器关闭时,会将Session的内容保存在硬盘上【钝化】,当服务器开启时,会将Session的内容在硬盘式重新加载【活化】) 。。

想要测试出Session的硬化和钝化,需要修改Tomcat的配置的。在META-INF下的context.xml文件中添加下面的代码:

8ac713b828ec27a49d45838ef365f860.png

测试

监听器和事件源

/** 由于涉及到了将内存的Session钝化到硬盘和用硬盘活化到内存中,所以需要实现Serializable接口** 该监听器是不需要在web.xml文件中配置的。但监听器要在事件源上实现接口* 也就是说,直接用一个类实现HttpSessionBindingListener和HttpSessionActivationListener接口是监听不到Session内对象的变化的。* 因为它们是感知自己在Session中的变化!* */

public classUser implementsHttpSessionBindingListener,HttpSessionActivationListener,Serializable {

private String username ;

publicString getUsername() {

return username;

}

publicvoidsetUsername(String username) {

this.username = username;

}

@Override

publicvoidsessionWillPassivate(HttpSessionEvent httpSessionEvent) {

HttpSession httpSession = httpSessionEvent.getSession();

System.out.println("钝化了");

}

@Override

publicvoidsessionDidActivate(HttpSessionEvent httpSessionEvent) {

HttpSession httpSession = httpSessionEvent.getSession();

System.out.println("活化了");

}

@Override

publicvoidvalueBound(HttpSessionBindingEvent httpSessionBindingEvent) {

System.out.println("绑定了对象");

}

@Override

publicvoidvalueUnbound(HttpSessionBindingEvent httpSessionBindingEvent) {

System.out.println("解除了对象");

}

}

测试代码

User user = new User();

request.getSession().setAttribute("aaa", user);

request.getSession().removeAttribute("aaa");

效果:

fac514beca59acaf239d27e52d84af55.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/291371.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用Brighter实现轻量型独立管道

前言上次,我们介绍了使用MediatR的Behaviors功能,在业务层实现管道模式。(《为什么应该在业务层实现管道模式,而不用ASP.NET Core Middleware实现 | 2点原因和实现方式》)但是,这种管道有个特点或者说缺点,不管你需不需…

CentOS6最小化安装默认启动的服务说明

centos6.2最小化安装后执行chkconfig --list,显示所有服务,如下图:下边分别进行说明:auditd:审核守护进程当 auditd 运行的时候,审核信息会被发送到一个用户配置日志文件中(默认的文件是 /var/log/audit/au…

[有奖励]GeneralUpdate开源项目招募开发者

[有奖励]GeneralUpdate开源项目招募开发者希望看到这篇文章的小伙伴,能看完这篇文章顺便帮忙给项目点一下“star”、转发、“在看”。先在这里谢谢各位了。github仓库地址:https://github.com/WELL-E/AutoUpdatergitee仓库地址:https://gitee…

C/C++ 读取16进制文件

1.为什么有这种需求 因为有些情况需要避免出现乱码。不管什么编码都是二进制的,这样表示为16进制就可以啦。 2.如何读取16进制文件 最近编程用这一问题,网上查了一下,感觉还是自己写吧。 16进制数据一般是:text0x340xb5...,就是0x…

基于PaddleOCR实现AI发票识别的Asp.net Core应用

简要介绍用户批量上传需要识别的照片,上传成功后,系统会启动Hangfire后台Job开始调用PaddleOCR服务返回结果,这个过程有点类似微服务的架构模型。PaddleOCRPaddleOCR是百度AI团队开源的一个项目,应该是目前所有免费开源OCR项目中识别效果最好的,具体可以通过PaddleO…

常用的搜索引擎dork (不断更新)

为什么80%的码农都做不了架构师?>>> pan.baidu.com xiaomi.rar 转载于:https://my.oschina.net/ecnu/blog/265731

学习笔记之卸载远程目标进程中的DLL模块(转)

学习笔记之卸载远程目标进程中的DLL模块 (2007-07-23 23:51:02)转载▼学习笔记之卸载远程目标进程中的DLL模块2007/7/231.首先得把DLL模块中的线程结束使用CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD,0);创建系统线程的快照然后用Thread32First()和Thread32Next()遍历系统中所…

Wow,一个免费、不怕打的评论插件!

快速给网站添加评论功能大家好,我是鱼皮,前段时间我自己做的网站不是被 DDOS 攻击了么?然后我就即时地给大家分享了一下我是怎么临时 “化解” 这次 DDOS 攻击的。结果我今天一看,好家伙,这个视频竟然都已经 120 w 播放…

MSSQLSERVER启动不了,报SQL Server 无法生成 FRunCM 线程

为什么80%的码农都做不了架构师?>>> 在启动MSSQLSERVER服务时,提示启动不了,在事件查看器中发现报错:SQL Server 无法生成 FRunCM 线程 网上搜了一下说是:MSSQLSERVER的协议中VIA协议被启用了,…

hdu 2648 Shopping

原题链接&#xff1a;http://acm.hdu.edu.cn/showproblem.php?pid2648 纯暴力的方法T_T。。。 如下: 1 #include<cstdio>2 #include<cstdlib>3 #include<string>4 #include<iostream>5 #include<algorithm>6 typedef char State[35];7 char *ta…

Windows导出所有计划任务方法

windows计划任务的命令为&#xff1a;schtasksSCHTASKS /parameter [arguments]描述:允许管理员创建、删除、查询、更改、运行和中止本地或远程系统上的计划任务。参数列表:/Create 创建新计划任务。/Delete 删除计划任务。/Query 显示所有计划任务。…

C# 使用多个异步方法

在一个异步方法中&#xff0c;可以调用一个或多个异步方法。如何编写代码&#xff0c;取决于一个异步方法的结果是否依靠于另一个异步方法。01 按顺序调用异步方法使用 await 关键字可以调用每个异步方法。在有些情况下&#xff0c;如果一个异步方法依赖另一个异步方法的结果&a…

Nova虚拟机启动提示libvirtError

OpenStack自动化安装基本折腾完毕&#xff0c;装一次大概也就10分钟&#xff0c;但是装完后今天我的虚拟机起不来&#xff0c;经过查找log发 现如下图提示&#xff1a; 已经到这里&#xff0c;说明已经过了nova-sheduler那一关&#xff0c;跟踪一下代码&#xff0c;也正是在调用…

ASP.NET Core使用功能开关控制路由访问

前言在前面的文章&#xff0c;我们介绍了使用Middleware有条件地允许访问路由&#xff08;《ASP.NET Core使用Middleware有条件地允许访问路由》&#xff09;。而对于一些试验性的功能&#xff0c;我们并不希望用密码去控制是否允许访问&#xff0c;而是想用一种开关的方式开放…

C#中的数组

欢迎您成为我的读者&#xff0c;希望这篇文章能给你一些帮助。前言前面的文章和大家一起看了C#中的异常&#xff0c;今天一起学习下C#中最基本的数据结构&#xff0c;数组的用法。数组实际上是由一个变量名称表示的一组同类型的数据元素。每个元素通过变量名称和一个或多个方括…

如何打卡后缀为3ds的文件

打开.3DS文件 3DS文件怎么打开&#xff1f; 用它吧&#xff1a;a3dsviewer&#xff0c;顾名思义&#xff0c;一个3D文件浏览工具&#xff0c;为用户提供一个快速和简单的3DS文件浏览器很容易。 这里是一些主要特点的“a3dsviewer”&#xff1a; 将3DS文件的POVRay格式。 输出的…

ASP.NET Core使用功能开关控制路由访问(续)

前言在前面的文章&#xff0c;我们介绍了使用功能开关控制路由访问。但其实我们使用了2个条件做的判断&#xff1a;var isDebugEndpoint context.Request.Path.Value.Contains("/test"); var debugEndpoint await _featureManager.IsEnabledAsync("ForbiddenD…

如何使用CDR智能填充工具

使用智能填充工具可以为任意的闭合区域填充颜色并设置轮廓。与其他填充工具不同&#xff0c;智能填充工具仅填充对象&#xff0c;它检测到区域的边缘并创建一个闭合路径&#xff0c;因此可以填充区域。例如&#xff0c;智能填充工具可以检测多个对象相交产生的闭合区域&#xf…

java对象引用出错_“Java有值传递和引用传递”为什么错了?

前言初学Java的时候&#xff0c;老师在课堂上说“Java有值传递和引用传递”&#xff0c;但网上“Java只有值传递”的呼声很高。本人在查找资料的过程中&#xff0c;在这两个说法之间反复横跳。经过本人的整理后&#xff0c;其实还真的是Java只有值传递。什么是值传递&#xff1…

程序员生存之道-教你如何在丛林中捕获食物

文章目录 &#x1f4a5; 序言&#x1f423; 躺&#x1f95d; 从零到一还是从零到100&#xff1f;&#x1f344; 螺丝钉文化&#x1f354; 价值分析&#x1f353; 长期主义者&#xff1f;&#x1f96c; 何为顺其自然&#xff1f;&#x1f308; 总结 &#x1f4a5; 序言 嗨&#…