2020/4/15学习笔记day40

java-day40

GUI事件监听总结

1.AWT事件模型概述

使用AWT或者Swing中的容器、组件和布局管理器就可以构建出图形界面,但是这时候该界面还并不能和用户进行交换,因为图形界面中的组件还没有添加事件监听器,所以还不能对用户在界面中的操作进行处理。

在Java事件模型中,必须存在事件对象、事件源、事件监听器三部分。事件对象是表示发生了什么事件,事件源表示是谁产生的这个事件对象,事件处理器接收到事件对象后,可以对这个事件进行处理。
事件模型中的三要素:事件对象、事件源、事件监听器
注:不光是GUI中,在java的其他地方也会使用到事件模型。

在Java中一个事件监听器就是指事件发生时被通知的对象。它有两个要求

首先,为了可以接收到特殊类型事件的通知,它必须在事件源中已经注册;

其次,它必须实现接收和处理事件的方法。

例如:
//btn就是事件源
JButton btn = new JButton("测试");
//给事件源btn注册事件监听器
//这里使用了匿名内部类对象作为监听器
btn.addActionListener(new ActionListener() {
    //监听器中实现接收和处理事件的方法
    //ActionEvent类型的引用e指向的就是按钮上所产生的事件对象
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("hello");
    }
});

XxxxListener 监听器接口
    事件源.addXxxxListener(new XxxxListener(){
        //实现接口中的抽象方法
    });

在事件源上注册好监听器之后,只要是在该事件源上产生了特定的事件对象,事件监听器就会自动被触发,并执行相应的方法处理。

例如:在上面的例子基础上
当我们使用鼠标点击btn这个按钮之后,产生了一个鼠标点击的事件对象(引用e会指向这个事件对象),然后注册的事件监听器会自动触发(这里的匿名内部类对象就是注册的监听器),并调用指定方法actionPerformed,对产生的事件进行处理。

2.事件源、事件对象、事件监听器

1)事件源

AWT和Swing中的几乎所有的组件都可以作为事件源,注意容器也是一种组件。
例如:窗口、面板、按钮、输入框、下拉类别的菜单、单选复选框、标签、滚动条、进度条等等
例如:AWT和Swing中的组件都是java.awt.Component类的子类型,Component类中定义了很多所有组件都可以调用的方法,这些方法中有很多是这种形式的:addXxxxListener
这些方法就是给组件中注册事件监听器的方法,只是不同类型的事件需要使用不同类型的监听器来监听,所以不同的addXxxxListener方法就表示给组件添加相应的事件监听器。(Xxxx代表事件的类型)

2)事件对象及其对应的处理接口(也就是事件监听器)

java.util.EventObject类

java.awt.Event类

java.awt.AWTEvent类

java.awt.event.ActionEvent类

java.awt.event.AdjustmentEvent类

java.awt.event.ComponentEvent类

java.awt.event.ContainerEvent类

java.awt.event.WindowEvent类

java.awt.event.FocusEvent类

java.awt.event.ItemEvent类

java.awt.event.TextEvent类

java.awt.event.KeyEvent类

java.awt.event.MouseEvent类

3.适配器 Adapter

很多监听器接口中都定义了很多个方法,每个方法负责处理一种产生事件的情况,我们编写实现类的时候就需要实现监听器接口中的所有方法,但是很多时候我们其实只需要调用接口中的一个方法,但是由于语法要求我们还是必须把接口中的所有抽象全都实现了。

例如: 点击按钮输出hello world

JButton btn = new JButton("test");
btn.addMouseListener(new MouseListener() {
    public void mouseClicked(MouseEvent e) {
        System.out.println("hello world");
    }
    public void mouseReleased(MouseEvent e) {}
    public void mousePressed(MouseEvent e) {}
    public void mouseExited(MouseEvent e) {}
    public void mouseEntered(MouseEvent e) {}
});

使用了MouseListener接口的匿名内部类对象,并且五个方法全都实现了,但是其实我们只需要调用mouseClicked方法.

为了处理这个代码中出现的情况,又引入了接口的适配器类:XxxxAdapter

MouseAdapter实现了MouseListener, MouseWheelListener, MouseMotionListener三个接口,并且把接口中抽象方法全都进行了空实现,将来我们只需要创建MouseAdapter类的匿名内部类然后重写我们想调用的方法即可
例如: 点击按钮输出hello world

JButton btn = new JButton("test");
btn.addMouseListener(new MouseAdapter() {
    public void mouseClicked(MouseEvent e) {
        System.out.println("hello world");
    }
});

​ 除了MouseAdapter实现MouseListener, MouseWheelListener, MouseMotionListener三个接口,是一个适配器类之外,还有其他的一些适配器类:

WindowAdapter适配器类实现了WindowListener, WindowStateListener, WindowFocusListener三个接口

ComponentAdapter适配器类实现了ComponentListener接口

ContainerAdapter适配器类实现了ContainerListener接口

FocusAdapter适配器类实现了FocusListener接口

KeyAdapter适配器类实现了KeyListener接口

MouseMotionAdapter适配器类实现了MouseMotionListener接口

HierarchyBoundsAdapter适配器类实现了HierarchyBoundsListener接口

4.定时器Timer

javax.swing.Timer类,可以定时触发事件(ActionEvent),调用监听器的指定方法。

例如:TimerTest1.java TimerTest2.java

JFrame jFrame = new JFrame();
JPanel panel = new JPanel();

JPanel north = new JPanel();
JButton startBtn = new JButton("开始");
JButton endBtn = new JButton("停止");

final Canvas canvas = new Canvas();

final Timer timer = new Timer(500,new ActionListener() {
    private int count;
    @Override
    public void actionPerformed(ActionEvent e) {
        if(count*10>=canvas.getWidth()){
            return ;
        }
        Graphics g = canvas.getGraphics();
        g.drawLine(count*10, 0, count*10, canvas.getWidth());
        count++;
    }
});

startBtn.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        timer.start();
    }
});
endBtn.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        timer.stop();
    }
});

north.add(startBtn);
north.add(endBtn);

panel.setLayout(new BorderLayout());
panel.add(canvas);

jFrame.add(north,BorderLayout.NORTH);
jFrame.add(panel);

jFrame.setSize(400, 400);
jFrame.setLocation(700, 300);
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jFrame.setVisible(true);

5.让当前类实现监听器接口

当前对象this就成为了监听器对象

例如:

public class Test extends JFrame implements ActionListener{
    private static final long serialVersionUID = 1L;

    private JPanel jPanel;
    private JButton btn;

    public Test() {
        setBounds(700, 500, 500, 500);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false);
        initComponet();
        setVisible(true);
    }

    private void initComponet(){
        //初始化组件
        jPanel = new JPanel();
        btn = new JButton("测试");

        //设置布局管理器并添加组件
        jPanel.add(btn);

        add(jPanel);

        //给组件添加事件监听器
        btn.addActionListener(this);
    }
    public void actionPerformed(ActionEvent e) {
        System.out.println("hello world");
    }

    public static void main(String[] args) {
        new Test();
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值