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点原因和实现方式》)但是,这种管道有个特点或者说缺点,不管你需不需…

Adobe Air 写文件如何换行

在用Air打log的时候发现,在字符串后面加"\n"并不能实现换行.百度一下才知道windows的换行是"\r\n".Mac OS 和 Linux换行符是"\n". 不同操作系统的换行符可能不一样.File有个静态属性File.lineEnding.用这个就可以了 下面是这个属性的官方帮助文档…

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

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

网页中插入javascript的几种方法

网页中插入javascript的方法常见的有两种&#xff1a; 一、直接使用html标记 JavaScript 可以出现在 html的任意地方。使用标记<script>…</script>&#xff0c;你可以在 HTML 文档的任意地方插入 JavaScript&#xff0c;甚至在<HTML>之前插入也不成问题。不…

LeetCode之Max Consecutive Ones

1、题目 Given a binary array, find the maximum number of consecutive 1s in this array. Example 1: Input: [1,1,0,1,1,1] Output: 3 Explanation: The first two digits or the last three digits are consecutive 1s.The maximum number of consecutive 1s is 3.Note: T…

java exception 行号_java日志记录错误的文件_方法_行号_报错信息

1、java日志记录错误的文件、方法、行号、报错信息StackTraceElement s e.getStackTrace()[0];1.1、记录保存的文件s.getFileName()1.2、记录保存的方法s.getMethodName()1.3、记录报错的行号 s.getLineNumber()1.4、记录报错的信息(不全面) e.getMessage()1.5、互利报错的类名…

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

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

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

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

【转】shell pipe与输入输出重定向的区别

http://www.cnblogs.com/chengmo/archive/2010/10/21/1856577.html转载于:https://www.cnblogs.com/qrlozte/p/4465120.html

LeetCode之Remove Duplicates from Sorted Array

1、题目 Given a sorted array, remove the duplicates in place such that each element appear only once and return the new length. Do not allocate extra space for another array, you must do this in place with constant memory. For example, Given input array nu…

Upgrade Oracle GI 11.2.0.4_to_12.1.0.2

12.1.0.2已经发布一段时间了&#xff0c;随着用户的增多&#xff0c;目前12C的版本稳定性&#xff0c;以及各个方面的功能性&#xff0c;得到大家的认可。很多用户&#xff0c;需要将数据库从低版本升级到12C&#xff0c;本文就升级过程&#xff0c;做了详细的记录。&#xff0…

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

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

java socket 路由_JAVA简单的Socket网络编程!CS

好久没写socket代码了&#xff0c;也忘了八九成了……话不多说&#xff01;直接上代码吧&#xff01;Server服务package test1;import java.io.*;import java.net.*;public class MyServer {public static void main(String[] args) throws IOException{ServerSocket server n…

linux dd 命令详解

1 磁盘管理1.1 dd1.1.1 功能说明读取&#xff0c;转换并输出数据。1.1.2 语法dd [bs<字节数>][cbs<字节数>][conv<关键字>][count<区块数>][ibs<字节数>][if<文件>][obs<字节数>][of<文件>][seek<区块数>][skip<区块…

LeetCode之Remove Duplicates from Sorted Array II

1、题目 Follow up for "Remove Duplicates": What if duplicates are allowed at most twice? For example, Given sorted array nums [1,1,1,2,2,3], Your function should return length 5, with the first five elements of nums being 1, 1, 2, 2 and 3. It …

Struts2 OGNL

OGNL(Object-Graph Navigation Language)的概念&#xff1a; OGNL是Object-Graph Navigation Language的缩写&#xff0c;全称为对象图导航语言&#xff0c;是一种功能强大的表达式语言&#xff0c;它通过简单一致的语法&#xff0c;可以任意存取对象的属性或者调用对象的方法&…

Android获取有线和无线(wifi)的IP地址

/*** 获取IP* * param context* return*/public static String getIP(Context context) {String ip "0.0.0.0";ConnectivityManager connectivityManager (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);NetworkInfo info connec…

如何实现线程池的 QueueUserWorkItem 方法的延续?

咨询区 PedroC88如果我将 Job 通过 QueueUserWorkItem 方法丢到线程池的话&#xff0c;请问我如何让程序在该 Job 完成后继续执行&#xff0c;我知道可以添加一些逻辑代码来完成此项功能&#xff0c;但我想知道有没有类似 Thread.Join() 或者怎么提取到被赋于 job 的线程 &…

LeetCode之Remove Duplicates from Sorted List

1、题目 Given a sorted linked list, delete all duplicates such that each element appear only once. For example, Given 1->1->2, return 1->2. Given 1->1->2->3->3, return 1->2->3. 1->2->2->2 return 1->2 1->2->3->…

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

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