Java-GUI編程之事件處理
事件處理
前面介紹了如何放置各種組件,從而得到了豐富多彩的圖形界面,但這些界面還不能響應用戶的任何操作。比如單擊前面所有窗口右上角的「X」按鈕,但窗口依然不會關閉。因為在 AWT 編程中 ,所有用戶的操作,都必須都需要經過一套事件處理機制來完成,而 Frame 和組件本身並沒有事件處理能力 。
GUI事件處理機制
定義:
當在某個組件上發生某些操作的時候,會自動的觸發一段代碼的執行。
在GUI事件處理機制中涉及到4個重要的概念需要理解:
事件源(Event Source) :操作發生的場所,通常指某個組件,例如按鈕、窗口等;
事件(Event):在事件源上發生的操作可以叫做事件,GUI會把事件都封裝到一個Event對象中,如果需要知道該事件的詳細信息,就可以通過Event對象來獲取。
事件監聽器(Event Listener):當在某個事件源上發生了某個事件,事件監聽器就可以對這個事件進行處理。
註冊監聽:把某個事件監聽器(A)通過某個事件(B)綁定到某個事件源(C)上,當在事件源C上發生了事件B之後,那麼事件監聽器A的代碼就會自動執行。

使用步驟:
1.創建事件源組件對象;
2.自定義類,實現XxxListener接口,重寫方法;
3.創建事件監聽器對象(自定義類對象)
4.調用事件源組件對象的addXxxListener方法完成註冊監聽
案例:
完成下圖效果,點擊確定按鈕,在單行文本域內顯示 hello world:

import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class EventDemo1 {
Frame frame = new Frame("這裡測試事件處理");
//事件源
Button button = new Button("確定");
TextField tf = new TextField(30);
public void init(){
//註冊監聽
button.addActionListener(new MyActionListener());
//添加組件到frame中
frame.add(tf);
frame.add(button,BorderLayout.SOUTH);
//設置frame最佳大小並可見
frame.pack();
frame.setVisible(true);
}
//自定義事件監聽器類
private class MyActionListener implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("用戶點擊了確定按鈕");
tf.setText("hello world");
}
}
public static void main(String[] args) {
new EventDemo1().init();
}
}
GUI中常見事件和事件監聽器
事件監聽器必須實現事件監聽器接口, AWT 提供了大量的事件監聽器接口用於實現不同類型的事件監聽器,用於監聽不同類型的事件 。 AWT 中提供了豐富的事件類,用於封裝不同組件上所發生的特定操作, AWT 的事件類都是 AWTEvent 類的子類 , AWTEvent是 EventObject 的子類。
事件
AWT把事件分為了兩大類:
1.低級事件:這類事件是基於某個特定動作的事件。比如進入、點擊、拖放等動作的鼠標事件,再比如得到焦點和失去焦點等焦點事件。
| 事件 | 觸發時機 |
|---|---|
| ComponentEvent | 組件事件 , 當 組件尺寸發生變化、位置發生移動、顯示/隱藏狀態發生改變時觸發該事件。 |
| ContainerEvent | 容器事件 , 當容器里發生添加組件、刪除組件時觸發該事件 。 |
| WindowEvent | 窗口事件, 當窗 口狀態發生改變 ( 如打開、關閉、最大化、最 小化)時觸發該事件 。 |
| FocusEvent | 焦點事件 , 當組件得到焦點或失去焦點 時觸發該事件 。 |
| KeyEvent | 鍵盤事件 , 當按鍵被按下、鬆開、單擊時觸發該事件。 |
| MouseEvent | 鼠標事件,當進行單擊、按下、鬆開、移動鼠標等動作 時觸發該事件。 |
| PaintEvent | 組件繪製事件 , 該事件是一個特殊的事件類型 , 當 GUI 組件調 用 update/paint 方法 來呈現自身時觸發該事件,該事件並非專用於事件處理模型 。 |
2.高級事件:這類事件並不會基於某個特定動作,而是根據功能含義定義的事件。
| 事件 | 觸發時機 |
|---|---|
| ActionEvent | 動作事件 ,當按鈕、菜單項被單擊,在 TextField 中按 Enter 鍵時觸發 |
| AjustmentEvent | 調節事件,在滑動條上移動滑塊以調節數值時觸發該事件。 |
| ltemEvent | 選項事件,當用戶選中某項, 或取消選中某項時觸發該事件 。 |
| TextEvent | 文本事件, 當文本框、文本域里的文本發生改變時觸發該事件。 |
事件監聽器
不同的事件需要使用不同的監聽器監聽,不同的監聽器需要實現不同的監聽器接口, 當指定事件發生後 , 事件監聽器就會調用所包含的事件處理器(實例方法)來處理事件 。
| 事件類別 | 描述信息 | 監聽器接口名 |
|---|---|---|
| ActionEvent | 激活組件 | ActionListener |
| ItemEvent | 選擇了某些項目 | ItemListener |
| MouseEvent | 鼠標移動 | MouseMotionListener |
| MouseEvent | 鼠標點擊等 | MouseListener |
| KeyEvent | 鍵盤輸入 | KeyListener |
| FocusEvent | 組件收到或失去焦點 | FocusListener |
| AdjustmentEvent | 移動了滾動條等組件 | AdjustmentListener |
| ComponentEvent | 對象移動縮放顯示隱藏等 | ComponentListener |
| WindowEvent | 窗口收到窗口級事件 | WindowListener |
| ContainerEvent | 容器中增加刪除了組件 | ContainerListener |
| TextEvent | 文本字段或文本區發生改變 | TextListener |
案例
案例一:
通過ContainerListener監聽Frame容器添加組件;
通過TextListener監聽TextFiled內容變化;
通過ItemListener監聽Choice條目選中狀態變化;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class ListenerDemo1 {
public static void main(String[] args) {
Frame frame = new Frame("這裡測試監聽器");
// 創建組件(事件源)
TextField tf = new TextField(30);
Choice names = new Choice();
names.add("柳岩");
names.add("舒淇");
names.add("閆妮");
// 給文本域添加TextListener,監聽內容的變化
tf.addTextListener(new TextListener() {
@Override
public void textValueChanged(TextEvent e) {
String text = tf.getText();
System.out.println("當前文本框中的內容為:" + text);
}
});
// 給下拉選擇框添加ItemListener,監聽條目選項的變化
names.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
Object item = e.getItem();
System.out.println("當前選中的條目為:" + item);
}
});
// 給frame註冊ContainerListener監聽器,監聽容器中組件的添加
frame.addContainerListener(new ContainerListener() {
@Override
public void componentAdded(ContainerEvent e) {
Component child = e.getChild();
System.out.println("frame中添加了:" + child);
}
@Override
public void componentRemoved(ContainerEvent e) {
}
});
// 添加到frame中
Box hBox = Box.createHorizontalBox();
hBox.add(names);
hBox.add(tf);
frame.add(hBox);
// 設置frame最佳大小並可見
frame.pack();
frame.setVisible(true);
}
}
案例2:
給Frame設置WindowListner,監聽用戶點擊 X 的動作,如果用戶點擊X,則關閉當前窗口
演示代碼2:
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class ListenerDemo2 {
public static void main(String[] args) {
Frame frame = new Frame("這裡測試WindowListener");
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
frame.setBounds(200,200,500,300);
frame.setVisible(true);
}
}
公眾號文章地址://mp.weixin.qq.com/s/0BOBUP2pFrizTJ4mZNQP6w
個人博客://kohler19.gitee.io/
公眾號:愚生淺末


