概述
-
事件表示程序和用戶之間的交互,例如在文本框中輸入,在列表框或組合框中選擇,選中複選框和單選框,單擊按鈕等。事件處理表示程序對事件的響應,對用戶的交互或者說對事件的處理是事件處理程序完成的。
-
當事件發生時,系統會自動捕捉這一事件,創建表示動作的事件對象並把它們分派給程序內的事件處理程序代碼。這種代碼確定瞭如何處理此事件以使用戶得到相應的回
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);
}
}