事件处理器的问题

SilentHunter460 2020-04-24 11:16:36
button1.addActionListener(new button1click()); 这句话只是实例化一个button1click对象,虽然它的类里边有public void actionPerformed(ActionEvent arg0)方法,但代码里没有一句话是调用这个方法,更没有传入ActionEvent对象类型的参数,为什么单击button1的时候会执行这个方法?


import java.awt.*;
import java.awt.event.*;

import javax.swing.*;

public class test {

public static void main(String[] args) {
JFrame window1 = newwindow(400, 300, "window1");
JButton button1 = newbutton(110, 35, "button1");
window1.add(button1);
button1.addActionListener(new button1click());
}

public static JFrame newwindow(int width, int height, String title) {
JFrame theframe = new JFrame(title);
theframe.setSize(width, height);
theframe.setLayout(new FlowLayout());
theframe.setVisible(true);
theframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
return theframe;
}

public static JButton newbutton(int width, int height, String title) {
JButton thebutton = new JButton(title);
thebutton.setPreferredSize(new Dimension(width, height));
return thebutton;
}
}

class button1click implements ActionListener {
@Override
public void actionPerformed(ActionEvent arg0) {
System.out.println(arg0.getActionCommand());
}
}
...全文
279 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
SilentHunter460 2020-04-28
  • 打赏
  • 举报
回复
引用 7 楼 捏造的信仰 的回复:
你不需要自己调用这个方法,你注册 listener 就是为了告诉 java,让它来调用这个方法。当用户点击按钮时,java 会捕获到这个事件,然后寻找已经注册的 listener 然后执行它们。
大概明白,反正这就是java的规则,事件处理就是不需要用户自己去调用方法,它java自己会搞定。 反正是死记硬背这个写法,达到我的目的即可。
捏造的信仰 2020-04-27
  • 打赏
  • 举报
回复
你不需要自己调用这个方法,你注册 listener 就是为了告诉 java,让它来调用这个方法。当用户点击按钮时,java 会捕获到这个事件,然后寻找已经注册的 listener 然后执行它们。
sunyiz 2020-04-26
  • 打赏
  • 举报
回复
你的疑问我大概明白什么意思了,你想要知道为什么点击一个JButton之后,
会执行 addActionListener 进去的那个 ActionListener 中的 actionPerformed 方法
这一点,要完全弄清楚,需要读大量的JDK源码,还要了解一下Swing的线程机制

这里我简单的描述一下这个过程:
首先,和Swing相关的有两个非常重要的线程,toolkit线程和EDT线程

toolkit:事件捕捉线程
该线程负责捕捉操作系统的各类输入,比如键盘和鼠标的操作,
然后根据“输入”的“内容”和“位置”,比如鼠标点击的位置,来决定对哪个控件进行哪种状态变换
这个线程虽然至关重要,但是你自己写的代码,不会影响也无法去干涉这个线程的任何逻辑

EDT:事件指派线程
就是在控件状态发生变化之后,会根据状态的变化,来生成一个对应的事件,
排队进入EDT的事件执行队列,然后由EDT来执行对应的代码
比如 JButton 的 ActionListener 中的 actionPerformed 方法,最终就会在这个线程中执行

这一流程综合起来描述如下:
toolkit线程捕捉到了鼠标点击,判断出点击位置有一个JButton,然后模拟出这个 JButton 的“按下”过程
这一“按下”过程,实际上是被封装成了一个事件,在 EDT 中被执行
在 EDT 中执行这个按钮“按下”过程时,JButton 的模型 DefaultButtonModel 中的 setPressed 方法被调用
setPressed 方法中会调用 fireActionPerformed 方法
而 fireActionPerformed 中会遍历注册到此 JButton 上的所有 ActionListener ,依次执行其 actionPerformed 方法
(注意以上所有过程,均在JDK的代码中已经实现)

所以,你用鼠标点击一个 JButton后,会执行 addActionListener 进去的 ActionListener 中的 actionPerformed 方法

qq_39936465 2020-04-26
  • 打赏
  • 举报
回复
引用 2 楼 qq_16774199 的回复:
你好,谢谢回复。你说的这个道理我懂,但还是有一个地方解释不通。 首先要调用一个类的实例方法,必须先new一个对象,用“对象.方法”才能调用。actionPerformed是button1click类的实例方法,但是代码里并没有出现new button1click().actionPerformed。
因为 button1click继承的是ActionListener这个接口,Actionlistener是一个当前容器的监控器与普通的类是有区别的。当加入监控器后,它会一直监控该容器。不同的容器有不同的事件发生,button只有点击事件,当该事件发生后会产生一个ActionEvent。一旦该事件变量会被button1click捕捉到,就会执行actionPerformed方法。这个和异常处理是很相似的。
hz890 2020-04-25
  • 打赏
  • 举报
回复
button1.addActionListener(new button1click()); 这句话只是实例化一个button1click对象 button1.addActionListener(new button1click());應該是為button1添加了事件偵聽器。“addActionListener”方法的用途“顧名思義”就是(為控件)設定事件監聽。new button1click()是為了滿足“addActionListener”方法的必要參數(該參數必須是ActionListener接口的實現類)。一旦控件的“addActionListener”方法被正確調用,則此控件便具備了偵聽事件的功能。對於button1而言,就可以響應用戶的單擊事件了。 以上供你參考。
qybao 2020-04-25
  • 打赏
  • 举报
回复
送佛送到西,给你找了个链接,例子虽然简单,但是阐明了基本原理 https://blog.csdn.net/Revivedsun/article/details/80151733
qybao 2020-04-25
  • 打赏
  • 举报
回复
引用 2 楼 qq_16774199 的回复:
[quote=引用 1 楼 hz890 的回复:] button1.addActionListener(new button1click()); 这句话只是实例化一个button1click对象 button1.addActionListener(new button1click());應該是為button1添加了事件偵聽器。“addActionListener”方法的用途“顧名思義”就是(為控件)設定事件監聽。new button1click()是為了滿足“addActionListener”方法的必要參數(該參數必須是ActionListener接口的實現類)。一旦控件的“addActionListener”方法被正確調用,則此控件便具備了偵聽事件的功能。對於button1而言,就可以響應用戶的單擊事件了。 以上供你參考。
你好,谢谢回复。你说的这个道理我懂,但还是有一个地方解释不通。 首先要调用一个类的实例方法,必须先new一个对象,用“对象.方法”才能调用。actionPerformed是button1click类的实例方法,但是代码里并没有出现new button1click().actionPerformed。[/quote]那是系统自动调用的,用户的输入被封装成事件类放在队列里,有个事件处理类从队列取出事件类挨个处理,根据事件的类型调用事件源(也就是你所谓的按钮)的相应的方法(如继承于Component类的processEvent之类的)。 具体自己谷歌百度一下事件驱动的gui模型吧,几句话没法说清楚。
SilentHunter460 2020-04-25
  • 打赏
  • 举报
回复
引用 1 楼 hz890 的回复:
button1.addActionListener(new button1click()); 这句话只是实例化一个button1click对象 button1.addActionListener(new button1click());應該是為button1添加了事件偵聽器。“addActionListener”方法的用途“顧名思義”就是(為控件)設定事件監聽。new button1click()是為了滿足“addActionListener”方法的必要參數(該參數必須是ActionListener接口的實現類)。一旦控件的“addActionListener”方法被正確調用,則此控件便具備了偵聽事件的功能。對於button1而言,就可以響應用戶的單擊事件了。 以上供你參考。
你好,谢谢回复。你说的这个道理我懂,但还是有一个地方解释不通。 首先要调用一个类的实例方法,必须先new一个对象,用“对象.方法”才能调用。actionPerformed是button1click类的实例方法,但是代码里并没有出现new button1click().actionPerformed。

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧