首页 > 编程笔记 > Java笔记 阅读:61

Java Swing事件监听器详解(附带实例)

Swing 提供了很多组件,这些组件本身并不带有任何功能。例如,在窗体中定义一个按钮,当用户单击该按钮时,虽然按钮可以凹凸显示,但在窗体中并没有实现任何功能。这时需要为按钮添加特定的事件监听器,该监听器负责处理用户单击按钮后实现的功能。

本节将着重讲解 Swing 中常用的 3 种事件监听器,即动作事件监听器、键盘事件监听器、鼠标事件监听器。

Swing ActionEvent动作事件

动作事件(ActionEvent)监听器是 Swing 中比较常用的事件监听器,很多组件的动作都会使用它进行监听,如按钮被单击等。

下表描述了动作事件监听器的接口与事件源等。

表:动作事件监听器
相关定义 实现方式 相关定义 实现方式
事件名 ActionEvent 添加监听方法 addActionListener()
事件源 JButton、JList、JTextField 等组件 删除监听方法 removeActionListener()
监听接口 ActionListener    

下面以单击按钮事件为例来说明动作事件监听器,当用户单击按钮时,将触发动作事件。

【实例 1】单击按钮后,修改按钮文本。创建 SimpleEvent 类,使该类继承 JFrame 类,在类中创建按钮组件,为按钮组件添加动作监听器,然后将按钮组件添加到窗体中。
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.WindowConstants;

public class SimpleEvent extends JFrame {
    private JButton jb = new JButton("我是假按钮,点击我");

    public SimpleEvent() {
        setLayout(null);
        setSize(200, 100);
        setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
        Container cp = getContentPane();
        cp.add(jb);
        jb.setBounds(10, 10, 150, 30);
        jb.addActionListener(new jbAction());
        setVisible(true);
    }

    class jbAction implements ActionListener {
        public void actionPerformed(ActionEvent arg0) {
            jb.setText("我被点击了");
        }
    }

    public static void main(String[] args) {
        new SimpleEvent();
    }
}
运行结果如下图所示:


图 1 按钮添加动作事件后的点击效果

在本实例中,为按钮设置了动作监听器。由于获取事件监听时需要获取实现 ActionListener 接口的对象,因此定义了一个内部类 jbAction 实现 ActionListener 接口,同时在该内部类中实现了 actionPerformed() 方法,也就是在 actionPerformed() 方法中定义当用户单击该按钮后实现怎样的功能。

Swing KeyEvent键盘事件

当向文本框中输入内容时,将发生键盘事件。KeyEvent 类负责捕获键盘事件,可以通过为组件添加实现了 KeyListener 接口的监听器类来处理相应的键盘事件。

KeyListener 接口共有 3 个抽象方法,分别在发生按键事件(按下并释放键)、按键被按下(手指按下键但不松开)和按键被释放(手指从按下的键上松开)时被触发,具体如下:
public interface KeyListener extends EventListener {
    public void keyTyped(KeyEvent e);    // 发生按键事件被触发
    public void keyPressed(KeyEvent e);  // 按键按下事件被触发
    public void keyReleased(KeyEvent e); // 按键释放事件被触发
}
在上述每个抽象方法中,均传入了 KeyEvent 类的对象。KeyEvent 类中比较常用的方法如下表所示:

表:KeyEvent类中的常用方法
方法 功能简介
getSource() 用来获得触发此次事件的组件对象,返回值为 Object 类型
getKeyChar() 用来获得与此次事件中的键相关联的字符
getKeyCode() 用来获得与此次事件中的键相关联的整数 keyCode
getKeyText(int keyCode) 用来获得描述 keyCode 的标签,如 A、F1 和 HOME 等
isActionKey() 用来查看此次事件中的键是否为“动作”键
isControlDown() 用来查看 Ctrl 键在此次事件中是否被按下,当返回 true 时表示被按下
isAltDown() 用来查看 Alt 键在此次事件中是否被按下,当返回 true 时表示被按下
isShiftDown() 用来查看 Shift 键在此次事件中是否被按下,返回 true 时表示被按下

在 KeyEvent 类中,以“VK_”开头的静态常量代表各个按键的 keyCode,可以通过这些静态常量判断事件中的按键,获得按键的标签。

【实例 2】通过键盘事件模拟一个虚拟键盘。首先需要自定义一个 addButtons() 方法,用来将所有的按键添加到一个 ArrayList 集合中,然后添加一个 JTextField 组件,并为该组件添加 addKeyListener 事件监听,在该事件监听中重写 keyPressed() 和 keyReleased() 方法,分别用来在按下和释放键时执行相应的操作。关键代码如下:
Color green = Color.GREEN;    // 定义 Color 对象,用来表示按下键的颜色
Color white = Color.WHITE;    // 定义 Color 对象,用来表示释放键的颜色
ArrayList<JButton> btns = new ArrayList<JButton>();  // 定义一个集合,用来存储所有的按键 ID

// 自定义一个方法,用来将容器中的所有 JButton 组件添加到集合中
private void addButtons() {
    for (Component cmp : contentPane.getComponents()) {  // 遍历面板中的所有组件
        if (cmp instanceof JButton) {                    // 判断组件的类型是否为 JButton 类型
            btns.add((JButton) cmp);                     // 将 JButton 组件添加到集合中
        }
    }
}

public KeyBoard() {                                      // KeyBoard 的构造方法
    ...
    textField = new JTextField();                        // 创建文本框组件
    textField.addKeyListener(new KeyAdapter() {          // 为文本框添加键盘事件的监听
        char word;                                       // 用于记录按下的字符

        public void keyPressed(KeyEvent e) {             // 按键按下时被触发
            word = e.getKeyChar();                       // 获取按下键表示的字符
            for (int i = 0; i < btns.size(); i++) {      // 遍历存储按键 ID 的 ArrayList 集合
                // 判断按键是否与遍历到的按键的文本相同
                if (String.valueOf(word).equalsIgnoreCase(btns.get(i).getText())) {
                    btns.get(i).setBackground(green);    // 将指定按键颜色设置为绿色
                }
            }
        }

        public void keyReleased(KeyEvent e) {            // 按键释放时被触发
            word = e.getKeyChar();                       // 获取释放键表示的字符
            for (int i = 0; i < btns.size(); i++) {      // 遍历存储按键 ID 的 ArrayList 集合
                // 判断按键是否与遍历到的按键的文本相同
                if (String.valueOf(word).equalsIgnoreCase(btns.get(i).getText())) {
                    btns.get(i).setBackground(white);    // 将指定按键颜色设置为白色
                }
            }
        }
    });

    panel.add(textField, BorderLayout.CENTER);           // 将文本框添加到中部区域
    textField.setColumns(10);                            // 设置文本框列数
}
运行本实例,将鼠标定位到文本框组件中,然后按下键盘上的按键,窗体中的相应按钮会变为绿色,释放按键时,相应按钮变为白色,效果如下图所示:


图 2 键盘事件

Swing MouseEvent鼠标事件

所有组件都能发生鼠标事件,MouseEvent 类负责捕获鼠标事件,可以通过为组件添加实现了 MouseListener 接口的监听器类来处理相应的鼠标事件。

MouseListener 接口共有 5 个抽象方法,分别在光标移入或移出组件、鼠标按键被按下或被释放和发生单击事件时被触发。所谓单击事件,就是按键被按下并被释放。需要注意的是,如果按键是在移出组件之后才被释放的,则不会触发单击事件。

MouseListener 接口的具体定义如下:
public interface MouseListener extends EventListener {
    public void mouseEntered(MouseEvent e);    // 光标移入组件时被触发
    public void mousePressed(MouseEvent e);    // 鼠标按键被按下时被触发
    public void mouseReleased(MouseEvent e);   // 鼠标按键被释放时被触发
    public void mouseClicked(MouseEvent e);    // 发生单击事件时被触发
    public void mouseExited(MouseEvent e);     // 光标移出组件时被触发
}
在上述每个抽象方法中,均传入了 MouseEvent 类的对象。MouseEvent 类中比较常用的方法如下表所示:

表:MouseEvent 类中的常用方法
方法 功能简介
getSource() 用来获得触发此事件的组件对象,返回值为 Object 类型
getButton() 用来获得代表此次按下、释放或单击的按键的 int 型值
getClickCount() 用来获得单击按钮的次数

当需要判断触发此次事件的按键时,可以通过下表中的静态常量判断由 getButton() 方法返回的 int 型值代表的键:

表:MouseEvent类中代表鼠标按键的静态常量
静态常量 常量值 代表的键
BUTTON1 1 代表鼠标左键
BUTTON2 2 代表鼠标滚轮
BUTTON3 3 代表鼠标右键

【实例 3】捕捉鼠标在窗体中的行为。创建一个窗体,在窗体中捕捉鼠标进入、移出和单击事件,关键代码如下:
private void mouseOper(MouseEvent e) {                   // 通过该值可以判断按下的是哪个键
    int i = e.getButton();
    if (i == MouseEvent.BUTTON1)
        System.out.println("按下的是鼠标左键");
    else if (i == MouseEvent.BUTTON2)
        System.out.println("按下的是鼠标滚轮");
    else if (i == MouseEvent.BUTTON3)
        System.out.println("按下的是鼠标右键");
}

public MouseEvent_Example() {
    // 省略部分代码
    final JLabel label = new JLabel();                   // 创建标签对象
    label.addMouseListener(new MouseListener() {
        public void mouseEntered(MouseEvent e) {         // 光标移入组件时被触发
            System.out.println("光标移入组件");
        }

        public void mousePressed(MouseEvent e) {         // 鼠标按键被按下时被触发
            System.out.print("鼠标按键被按下,");
            mouseOper(e);
        }

        public void mouseReleased(MouseEvent e) {        // 鼠标按键被释放时被触发
            System.out.print("鼠标按键被释放,");
            mouseOper(e);
        }

        public void mouseClicked(MouseEvent e) {         // 发生单击事件时被触发
            System.out.print("单击了鼠标按键,");
            mouseOper(e);
            int clickCount = e.getClickCount();          // 获取鼠标单击次数
            System.out.println("单击次数为" + clickCount + "下");
        }

        public void mouseExited(MouseEvent e) {          // 光标移出组件时被触发
            System.out.println("光标移出组件");
        }
    });
    // 省略部分代码
}
运行结果如下图所示:


图 3 程序弹出的窗体

首先将光标移入窗体,然后单击,接着双击,最后将光标移出窗体,在控制台中将得到如下图所示的信息。当双击鼠标时,第一次单击鼠标将触发一次单击事件。


图 4 在控制台中输出的日志

相关文章