Java 1.0 事件模型:所有元件事件集中在 handleEvent() 或 action() 中,靠 if (evt.target == btn1) 硬編碼判斷,違反開放封閉原則,擴充性極差。
Java 1.1 委派事件模型:事件源 (元件) 產生 事件物件 (ActionEvent 等),分派給註冊的 事件監聽器 (ActionListener)。三者解耦,符合觀察者模式。
ActionEvent, MouseEvent...),封裝事件狀態。actionPerformed(ActionEvent)),單一方法介面最簡潔。addXXXListener()/removeXXXListener(),編譯期型別安全。//: Button2New.java
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
public class Button2New extends Applet {
Button b1 = new Button("Button 1"), b2 = new Button("Button 2");
public void init() {
b1.addActionListener(new B1()); // 註冊監聽器
b2.addActionListener(new B2());
add(b1); add(b2);
}
class B1 implements ActionListener {
public void actionPerformed(ActionEvent e) {
getAppletContext().showStatus("Button 1");
}
}
class B2 implements ActionListener {
public void actionPerformed(ActionEvent e) {
getAppletContext().showStatus("Button 2");
}
}
} ///:~
| 維度 | 舊模型 (action) | 新模型 (ActionListener) |
|---|---|---|
| 事件判斷 | 手動 if/else 檢查 evt.target | 自動分派,各監聽器專責專司 |
| 事件物件 | 通用 Event,需向下轉型 | 專用 ActionEvent,直接存取語意資訊 |
| 回傳值 | 需回傳 boolean 標示是否處理 | 無回傳值,框架自動管理 |
| 基礎類呼叫 | 需手動 super.action() | 無需管基礎類,框架負責 |
| 程式碼組織 | 集中式、膨脹 | 分散式、內聚、可重用 |
監聽器常實作為內部類,兩大優勢:
t1, bl 等),無需額外建構子傳參,解決「回調」問題,避免 C++ 式函數指標複雜性。class B1 implements ActionListener {
public void actionPerformed(ActionEvent e) {
t.setText(Integer.toString(bl.calculation1(getValue(t)))); // 直接用外部 bl、t、getValue()
}
}
新事件模型的 addXXXListener() 命名慣例,正是 Java Beans 自省機制識別事件的依據:工具可自動發現元件支援哪些事件,支援視覺化建構器拖拉元件、連線事件。
b1.addActionListener(e -> showStatus("Button 1")); 替代匿名內部類。b1.addActionListener(this::handleButton1);掌握新事件模型精髓——關注點分離、型別安全、擴充性——是從 AWT 邁向 Swing、JavaFX、Spring、現代響應式架構的基石。