Java 1.1 委派事件模型中,每個元件透過 addXXXListener()/removeXXXListener() 註冊特定事件監聽器。本文提供三張核心對照表:事件→監聽器→支援元件、元件→支援事件、監聽器介面→必須實作方法,並深入解析適配器模式簡化多方法介面實作。
| 事件 / 監聽器 / 註冊方法 | 支援元件 |
|---|---|
ActionEvent / ActionListeneradd/removeActionListener() | Button, List, TextField, MenuItem, CheckboxMenuItem, Menu, PopupMenu |
AdjustmentEvent / AdjustmentListeneradd/removeAdjustmentListener() | Scrollbar, 實作 Adjustable 介面的自訂元件 |
ComponentEvent / ComponentListeneradd/removeComponentListener() | 所有 Component 子類:Button, Canvas, Checkbox, Choice, Container, Panel, Applet, ScrollPane, Window, Dialog, FileDialog, Frame, Label, List, Scrollbar, TextArea, TextField |
ContainerEvent / ContainerListeneradd/removeContainerListener() | Container 子類:Panel, Applet, ScrollPane, Window, Dialog, FileDialog, Frame |
FocusEvent / FocusListeneradd/removeFocusListener() | 所有 Component 子類 (同上) |
KeyEvent / KeyListeneradd/removeKeyListener() | 所有 Component 子類 (同上) |
MouseEvent / MouseListeneradd/removeMouseListener() | 所有 Component 子類 (同上) |
MouseEvent / MouseMotionListeneradd/removeMouseMotionListener() | 所有 Component 子類 (同上) |
WindowEvent / WindowListeneradd/removeWindowListener() | Window 子類:Dialog, FileDialog, Frame |
ItemEvent / ItemListeneradd/removeItemListener() | Checkbox, CheckboxMenuItem, Choice, List, 實作 ItemSelectable 介面的元件 |
TextEvent / TextListeneradd/removeTextListener() | TextComponent 子類:TextArea, TextField |
註:MouseEvent 同時用於點擊與移動,無獨立 MouseMotionEvent。
| 元件類型 | 支援事件 |
|---|---|
| Adjustable | AdjustmentEvent |
| Applet | ContainerEvent, FocusEvent, KeyEvent, MouseEvent, ComponentEvent |
| Button | ActionEvent, FocusEvent, KeyEvent, MouseEvent, ComponentEvent |
| Canvas | FocusEvent, KeyEvent, MouseEvent, ComponentEvent |
| Checkbox | ItemEvent, FocusEvent, KeyEvent, MouseEvent, ComponentEvent |
| CheckboxMenuItem | ActionEvent, ItemEvent |
| Choice | ItemEvent, FocusEvent, KeyEvent, MouseEvent, ComponentEvent |
| Component | FocusEvent, KeyEvent, MouseEvent, ComponentEvent |
| Container | ContainerEvent, FocusEvent, KeyEvent, MouseEvent, ComponentEvent |
| Dialog | ContainerEvent, WindowEvent, FocusEvent, KeyEvent, MouseEvent, ComponentEvent |
| FileDialog | ContainerEvent, WindowEvent, FocusEvent, KeyEvent, MouseEvent, ComponentEvent |
| Frame | ContainerEvent, WindowEvent, FocusEvent, KeyEvent, MouseEvent, ComponentEvent |
| Label | FocusEvent, KeyEvent, MouseEvent, ComponentEvent |
| List | ActionEvent, FocusEvent, KeyEvent, MouseEvent, ItemEvent, ComponentEvent |
| Menu | ActionEvent |
| MenuItem | ActionEvent |
| Panel | ContainerEvent, FocusEvent, KeyEvent, MouseEvent, ComponentEvent |
| PopupMenu | ActionEvent |
| Scrollbar | AdjustmentEvent, FocusEvent, KeyEvent, MouseEvent, ComponentEvent |
| ScrollPane | ContainerEvent, FocusEvent, KeyEvent, MouseEvent, ComponentEvent |
| TextArea | TextEvent, FocusEvent, KeyEvent, MouseEvent, ComponentEvent |
| TextComponent | TextEvent, FocusEvent, KeyEvent, MouseEvent, ComponentEvent |
| TextField | ActionEvent, TextEvent, FocusEvent, KeyEvent, MouseEvent, ComponentEvent |
| Window | ContainerEvent, WindowEvent, FocusEvent, KeyEvent, MouseEvent, ComponentEvent |
| 監聽器介面 (適配器) | 介面方法 |
|---|---|
| ActionListener | actionPerformed(ActionEvent) |
| AdjustmentListener | adjustmentValueChanged(AdjustmentEvent) |
| ComponentListener (ComponentAdapter) | componentHidden/Shown/Moved/Resized(ComponentEvent) |
| ContainerListener (ContainerAdapter) | componentAdded/Removed(ContainerEvent) |
| FocusListener (FocusAdapter) | focusGained/Lost(FocusEvent) |
| KeyListener (KeyAdapter) | keyPressed/Released/Typed(KeyEvent) |
| MouseListener (MouseAdapter) | mouseClicked/Entered/Exited/Pressed/Released(MouseEvent) |
| MouseMotionListener (MouseMotionAdapter) | mouseDragged/Moved(MouseEvent) |
| WindowListener (WindowAdapter) | windowOpened/Closing/Closed/Activated/Deactivated/Iconified/Deiconified(WindowEvent) |
| ItemListener | itemStateChanged(ItemEvent) |
| TextListener | textValueChanged(TextEvent) |
MouseEvent → MouseListener)mouseMoved())add + 介面名 (如 addMouseMotionListener())單方法介面 (ActionListener, ItemListener, TextListener, AdjustmentListener) 直接實作即可。多方法介面若逐一實作空方法極繁瑣,Java 提供 適配器類別 (Adapter) 供繼承覆寫:
// 典型視窗關閉處理
class MyWindowListener extends WindowAdapter {
public void windowClosing(WindowEvent e) { System.exit(0); }
}
WindowAdapter 已提供所有方法的空實作,僅覆寫關心的 windowClosing() 即可。
// 錯誤:WindowClosing (大寫 W) → 新方法,非覆寫
class MyWindowListener extends WindowAdapter {
public void WindowClosing(WindowEvent e) { System.exit(0); } // 無效!
}
編譯通過、執行無誤,但關閉視窗不退出程式。@Override 註解 (Java 5+) 可編譯期攔截此類錯誤,強烈建議永遠加上。
EventListenerList 高效管理監聽器。EventHandler<T> 函數式介面 + Lambda,更簡潔。ApplicationEventPublisher) 實現業務層解耦事件驅動。熟記此對照表,除錯「為什麼我的監聽器不觸發」將從猜謎變成查表驗證。