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

Java AWT 動態事件綁定:執行時靈活增刪監聽器

     編輯:Java 相關知識

新事件模型帶來的靈活性

Java 1.1 引入的委派事件模型,讓元件可動態註冊/移除多個監聽器,不再像 1.0 版那般被迫在 handleEvent() 中硬編碼判斷邏輯。本文透過實例展示如何在執行期動態增減 ActionListener,實現更靈活的互動行為。

核心範例:按鈕點擊動態管理監聽器

//: DynamicEvents.java
import java.awt.*;
import java.awt.event.*;
import java.util.*;

public class DynamicEvents extends Frame {
    Vector<ActionListener> v = new Vector<>();
    int i = 0;
    Button b1 = new Button("Button 1"), b2 = new Button("Button 2");

    public DynamicEvents() {
        setLayout(new FlowLayout());
        // 每個按鈕初始註冊兩個監聽器
        b1.addActionListener(new B());
        b1.addActionListener(new B1());
        b2.addActionListener(new B());
        b2.addActionListener(new B2());
        add(b1); add(b2);
    }

    // 共用基礎監聽器
    class B implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            System.out.println("A button was pressed");
        }
    }

    // 計數監聽器
    class CountListener implements ActionListener {
        int index;
        CountListener(int i) { index = i; }
        public void actionPerformed(ActionEvent e) {
            System.out.println("Counted Listener " + index);
        }
    }

    // Button 1 被按:為 Button 2 新增一個計數監聽器
    class B1 implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            System.out.println("Button 1 pressed");
            ActionListener a = new CountListener(i++);
            v.addElement(a);
            b2.addActionListener(a);
        }
    }

    // Button 2 被按:移除最後一個計數監聽器
    class B2 implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            System.out.println("Button 2 pressed");
            int end = v.size() - 1;
            if (end >= 0) {
                b2.removeActionListener((ActionListener)v.elementAt(end));
                v.removeElementAt(end);
            }
        }
    }

    public static void main(String[] args) {
        Frame f = new DynamicEvents();
        f.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) { System.exit(0); }
        });
        f.setSize(300, 200);
        f.setVisible(true);
    }
} ///:~

關鍵技術點解析

1. 多播事件

單一元件可註冊多個同類型監聽器(addActionListener 可重複呼叫)。事件觸發時,所有監聽器依註冊順序依序被通知。若元件設計為單播(如某些自訂元件),嘗試註冊第二個監聽器會拋出 TooManyListenersException。

2. 動態增減

  • 新增:addXXXListener(Listener l)
  • 移除:removeXXXListener(Listener l),需持有監聽器參考才能精準移除。

範例中使用 Vector 保存動態建立的 CountListener 參考,實現「疊加/移除」行為。

3. 執行順序無保證

雖然實務上多依註冊順序觸發,但規範不保證呼叫順序。邏輯不應依賴監聽器執行順序。

實務應用場景

  • 外掛系統:執行期載入/卸載事件處理器。
  • 模式切換:編輯/檢視模式下啟用不同滑鼠/鍵盤監聽器。
  • 條件式監控:特定業務狀態下才啟用審計/日誌監聽器。

現代化對應

Swing/JavaFX 繼承此模型。現代開發常搭配:

  • Lambda 表達式 簡化匿名類別寫法。
  • 事件總線 (EventBus, RxJava) 實現跨元件解耦通訊。
  • 屬性綁定 (JavaFX Properties) 替代低層級事件處理。

掌握動態事件綁定,能讓你的 UI 邏輯更模組化、更適應複雜互動需求。

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