Java中的Listener和Adapter

⌚Time: 2022-08-10 17:40:38

👨‍💻Author: Jack Ge

问AI:java里的Listener和Adapter都是干什么的?

在Java中,**Listener(监听器)Adapter(适配器)**都是事件处理机制的重要组成部分,主要用于GUI编程(如Swing/AWT)和其他事件驱动场景。

一、Listener(监听器) - 事件处理器

作用

监听器是事件处理的接口,定义了响应特定事件的方法。

特点

  1. 接口形式:必须实现所有方法
  2. 事件驱动:当事件发生时自动调用
  3. 多重实现:一个类可以实现多个监听器接口

常见监听器示例

// ActionListener - 处理按钮点击等动作事件
button.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("按钮被点击了!");
    }
});

// MouseListener - 处理鼠标事件
component.addMouseListener(new MouseListener() {
    @Override
    public void mouseClicked(MouseEvent e) {}
    
    @Override
    public void mousePressed(MouseEvent e) {}
    
    @Override
    public void mouseReleased(MouseEvent e) {}
    
    @Override
    public void mouseEntered(MouseEvent e) {}
    
    @Override
    public void mouseExited(MouseEvent e) {}
});

二、Adapter(适配器) - 监听器的便利类

作用

适配器是实现了监听器接口的空实现类,提供默认实现,让开发者只覆盖需要的方法。

为什么需要适配器?

有些监听器接口有很多方法(如MouseListener有5个方法),但通常我们只需要其中1-2个。适配器避免了必须实现所有方法的麻烦。

适配器示例

// 使用适配器,只需要覆盖需要的方法
component.addMouseListener(new MouseAdapter() {
    @Override
    public void mouseClicked(MouseEvent e) {
        System.out.println("鼠标点击了");
    }
    // 不需要实现其他4个方法
});

// WindowAdapter示例
frame.addWindowListener(new WindowAdapter() {
    @Override
    public void windowClosing(WindowEvent e) {
        System.exit(0);
    }
    // 不需要实现其他6个方法
});

三、Listener vs Adapter 对比

特性 Listener(接口) Adapter(类)
形式 接口 抽象类/具体类
方法实现 必须实现所有方法 提供空实现,可选择覆盖
使用场景 需要处理所有事件 只关心部分事件
灵活性 高(可完全自定义) 方便(减少代码量)
继承关系 可多实现 只能单继承

四、实际应用示例

场景1:按钮点击 + 鼠标悬停

JButton button = new JButton("测试");

// 使用监听器处理点击(只有一个方法)
button.addActionListener(e -> {
    System.out.println("按钮点击");
});

// 使用适配器处理鼠标事件(只需要两个方法)
button.addMouseListener(new MouseAdapter() {
    @Override
    public void mouseEntered(MouseEvent e) {
        button.setText("鼠标进来了");
    }
    
    @Override
    public void mouseExited(MouseEvent e) {
        button.setText("鼠标出去了");
    }
});

场景2:键盘事件处理

// KeyListener有3个方法,使用适配器只需覆盖需要的
textField.addKeyListener(new KeyAdapter() {
    @Override
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_ENTER) {
            System.out.println("按了回车键");
        }
    }
});

五、自定义适配器示例

// 创建自定义适配器
public class SimpleActionAdapter implements ActionListener {
    private Runnable task;
    
    public SimpleActionAdapter(Runnable task) {
        this.task = task;
    }
    
    @Override
    public void actionPerformed(ActionEvent e) {
        if (task != null) {
            task.run();
        }
    }
}

// 使用
button.addActionListener(new SimpleActionAdapter(() -> {
    System.out.println("执行任务");
}));

总结

  1. Listener是接口:定义事件处理方法,必须实现所有方法
  2. Adapter是类:提供监听器接口的默认实现,方便只覆盖部分方法
  3. 选择原则
    • 需要处理所有事件 → 实现Listener
    • 只关心部分事件 → 继承Adapter
    • 现代Java中,Lambda表达式常替代只有一个方法的监听器

这种设计模式体现了接口隔离原则,既保持了接口的完整性,又提供了使用的便利性。