概述
-
事件表示程序和用户之间的交互,例如在文本框中输入,在列表框或组合框中选择,选中复选框和单选框,单击按钮等。事件处理表示程序对事件的响应,对用户的交互或者说对事件的处理是事件处理程序完成的。
-
当事件发生时,系统会自动捕捉这一事件,创建表示动作的事件对象并把它们分派给程序内的事件处理程序代码。这种代码确定了如何处理此事件以使用户得到相应的回
Swing事件模型
- 在事件处理的过程中,主要涉及三类对象。
- Event(事件):用户对组件的一次操作称为一个事件,以类的形式出现。例如,键盘操作对应的事件类是 KeyEvent。
- Event Source(事件源):事件发生的场所,通常就是各个组件,例如按钮 Button。
- Event Handler(事件处理者):接收事件对象并对其进行处理的对象事件处理器,通常就是某个 Java 类中负责处理事件的成员方法。
- 例如,如果鼠标单击了按钮对象 Button,则该按钮 Button 就是事件源,而 Java 运行时系统会生成 ActionEvent 类的对象 ActionEvent,该对象中描述了单击事件发生时的一些信息。之后,事件处理者对象将接收由 Java 运行时系统传递过来的事件对象 ActionEvent,并进行相应的处理。事件处理模型如图 1 所示。
由于同一个事件源上可能发生多种事件,因此,Java 采取了授权模型(Delegation Model),事件源可以把在其自身上所有可能发生的事件分别授权给不同的事件处理者来处理。例如,在 Panel 对象上既可能发生鼠标事件,也可能发生键盘事件,该 Panel 对象可以授权给事件处理者 a 来处理鼠标事件,同时授权给事件处理者 b 来处理键盘事件。
有时也将事件处理者称为监听器,主要原因在于监听器时刻监听事件源上所有发生的事件类型,一旦该事件类型与自己所负责处理的事件类型一致,就马上进行处理。授权模型把事件的处理委托给外部的处理实体进行处理,实现了将事件源和监听器分开的机制。
事件处理者(监听器)通常是一个类,该类如果能够处理某种类型的事件,就必须实现与该事件类型相对的接口。例如,一个 ButtonHandler 类之所以能够处理 ActionEvent 事件,原因在于它实现了与 ActionEvent 事件对应的接口 ActionListener。每个事件类都有一个与之相对应的接口。
动作事件监听器
动作事件监听器是 Swing 中比较常用的事件监听器,很多组件的动作都会使用它监听,像按钮被里击、列表框中选择一项等。与动作事件监听器有关的信息如下。
- 事件名称:ActionEvent(动作事件)。
- 事件监听接口: ActionListener。
- 事件相关方法:addActionListener() 添加监听,removeActionListener() 删除监听。
- 涉及事件源:JButton、JList、JTextField 等。
Demo
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class DemoActionEvent {
public static int count = 0;
public static void main(String[] args) {
JFrame jFrame = new JFrame("动作事件监听器示例");
Container container = jFrame.getContentPane();
JButton jButton = new JButton("点击");
JPanel jPanel = new JPanel(new BorderLayout());
//设置边框
jPanel.setBorder(new EmptyBorder(5,5,5,5));
jPanel.add(jButton);
JLabel jLabel = new JLabel();
//设置字体样式
jLabel.setFont(new Font("微软雅黑",Font.BOLD,14));
jPanel.add(jLabel,BorderLayout.SOUTH);
jButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
jLabel.setText("按钮被单击了"+(++count)+"次");
}
});
container.add(jPanel);
jFrame.setSize(400,300);
jFrame.setVisible(true);
jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
}
Demo运行结果如下
焦点事件监听器
除了单击事件外,焦点事件监听器在实际项目中应用也比较广泛,例如将光标离开文本框时弹出对话框,或者将焦点返回给文本框等。
与焦点事件监听器有关的信息如下。
- 事件名称:FocusEvent。
- 事件监听接口: FocusListener。
- 事件相关方法:addFocusListener() 添加监听,removeFocusListener() 删除监听。
- 涉及事件源:Component 以及派生类。
- FocusEvent 接口定义了两个方法,分别为 focusGained() 方法和 focusLost() 方法,其中 focusGained() 方法是在组件获得焦点时执行,focusLost() 方法是在组件失去焦点时执行。
Demo
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
public class DemoFocusListener {
public static void main(String[] args) {
JFrame jFrame = new JFrame("焦点监听器示例");
Container container = jFrame.getContentPane();
//设置面板布局为边界布局
JPanel jPanel = new JPanel(new BorderLayout(0,0));
//设置边框
jPanel.setBorder(new EmptyBorder(5,5,5,5));
JLabel jLabel = new JLabel();
jLabel.setFont(new Font("楷体",Font.BOLD,16));
JTextField jTextField = new JTextField();
//为JTextField组件对象设置焦点监听
jTextField.addFocusListener(new FocusListener() {
@Override
public void focusGained(FocusEvent e) {
jLabel.setText("文本框获得焦点,正在输入内容");
}
@Override
public void focusLost(FocusEvent e) {
jLabel.setText("文本框失去焦点,内容输入完成");
}
});
JButton jButton = new JButton("单击");
//将组件放入容器和面板
jPanel.add(jTextField);
jPanel.add(jLabel,BorderLayout.NORTH);
jPanel.add(jButton,BorderLayout.SOUTH);
container.add(jPanel);
jFrame.setSize(400,300);
jFrame.setVisible(true);
jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
}
Demo运行结果如下
监听列表选择事件
- 列表框控件 JList 会显示很多项供用户选择,通常在使用时会根据用户选择的列表项完成不同的操作。
本案例将介绍如何监听列表项的选择事件,以及事件监听器的处理方法,实现过程如下
Demo
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.*;
public class DemoListSelectionListener {
public static void main(String[] args) {
JFrame jFrame = new JFrame("焦点监听器示例");
Container container = jFrame.getContentPane();
//设置面板布局为边界布局
JPanel jPanel = new JPanel(new BorderLayout(0,0));
//设置边框
jPanel.setBorder(new EmptyBorder(5,5,5,5));
String[] arr = {
"<<Java从入门到精通>>",
"<<C从入门到精通>>",
"<<C++从入门到精通>>",
"<<PHP从入门到精通>>",
"<<Python从入门到精通>>",
"<<Go从入门到精通>>"
};
JList jList = new JList(arr);
JLabel jLabel = new JLabel();
//设置监听列表选择事件
jList.addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
System.out.println(e);
String str = jList.getSelectedValue()+"";
jLabel.setText("选择课程: "+str);
}
});
jList.setBackground(Color.CYAN);
//将组件添加进容器,面板
jPanel.add(jList);
jPanel.add(jLabel,BorderLayout.SOUTH);
container.add(jPanel);
//设置窗体的大小,可见,关闭方式
jFrame.setSize(400,300);
jFrame.setVisible(true);
jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
}