首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 1.0 handleEvent() 深度解析:事件攔截、列表單擊修正與超類呼叫鏈陷阱

     編輯:Java 相關知識

handleEvent() 核心地位

Java 1.0 事件模型中,handleEvent(Event evt) 是所有事件的總入口。每個事件發生時,目標元件的 handleEvent() 被自動調用。預設實作會分派給 action()、mouseDown()、keyDown() 等具體方法。

為何覆寫 handleEvent()

  • action() 僅處理「標準動作」(按鈕點擊、選單選擇、列表雙擊)
  • 需捕捉單擊、滑鼠移動、焦點變化等非標準動作事件
  • 需在分派前攔截/過濾/記錄事件

實戰範例:List2 — 修正 List 單擊無反應問題

//: List2.java
import java.awt.*;
import java.applet.*;

public class List2 extends Applet {
    String[] flavors = {"Chocolate","Strawberry","Vanilla Fudge Swirl","Mint Chip",
                        "Mocha Almond Fudge","Rum Raisin","Praline Cream","Mud Pie"};
    List lst = new List(6, true); // 顯示6項,允許多選
    TextArea t = new TextArea(flavors.length, 30);
    Button b = new Button("test");
    int count = 0;

    public void init() {
        t.setEditable(false);
        for (int i=0; i<4; i++) lst.addItem(flavors[count++]);
        add(t); add(lst); add(b);
    }

    // 覆寫 handleEvent 攔截 LIST_SELECT/DESELECT
    public boolean handleEvent(Event evt) {
        if (evt.id == Event.LIST_SELECT || evt.id == Event.LIST_DESELECT) {
            if (evt.target.equals(lst)) {
                t.setText("");
                String[] items = lst.getSelectedItems();
                for (String item : items) t.appendText(item + "\n");
            } else return super.handleEvent(evt);
        } else return super.handleEvent(evt);
        return true;
    }

    // 按鈕動作仍由 action() 處理
    public boolean action(Event evt, Object arg) {
        if (evt.target.equals(b)) {
            if (count < flavors.length) lst.addItem(flavors[count++], 0); // 插入頂部
        } else return super.action(evt, arg);
        return true;
    }
} ///:~

關鍵技術點

1. 事件 ID 判斷

evt.id == Event.LIST_SELECT 捕捉選擇/取消選擇事件。Java 1.0 事件 ID 定義在 Event 類別常數中。

2. 目標元件比對

evt.target.equals(lst) 確認事件來源。關鍵習慣:即使目前只有一個列表,也要比對目標,否則日後新增列表即成 Bug。

3. 超類呼叫鐵律

// 必須回傳 super.handleEvent(evt) 處理不關心的事件
else return super.handleEvent(evt);

若直接 return false 或省略,父類 action()、mouseDown() 等將永遠不被調用。這是 Java 1.0 最易犯的錯誤。

4. 回傳值語意

  • true:事件已處理,不再傳播
  • false / super.handleEvent():事件未處理,繼續傳播/讓父類處理

Shift+單擊多選限制

Windows 原生 List 支援 Shift+單擊範圍選取,但 Java 1.0 handleEvent() 無法攔截「哪個項目被單擊時 Shift 鍵狀態」。Java 1.1 新事件模型將滑鼠/鍵盤事件分派至列表,始能實現完整修正。

現代化對應 (Java 1.1+)

// ItemListener 處理選擇變更 (單擊/鍵盤/程式觸發皆捕捉)
list.addItemListener(e -> {
    if (e.getStateChange() == ItemEvent.SELECTED || e.getStateChange() == ItemEvent.DESELECTED) {
        String[] items = list.getSelectedItems();
        // 更新 UI...
    }
});

// MouseListener 捕捉單擊細節 (含修飾鍵)
list.addMouseListener(new MouseAdapter() {
    public void mouseClicked(MouseEvent e) {
        if (e.getClickCount() == 1 && (e.getModifiersEx() & InputEvent.SHIFT_DOWN_MASK) != 0) {
            // Shift+單擊邏輯
        }
    }
});

總結

handleEvent() 是 Java 1.0 事件模型的「總開關」,功能強大但極易出錯:忘記呼叫 super、回傳值錯誤、事件 ID 遺漏。Java 1.1 委派模型徹底解決此問題:各司其職、型別安全、多播支援、無超類鏈陷阱。現代開發請完全使用監聽器模型,僅在維護極舊代碼時接觸 handleEvent()。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved