Swing 事件處理是 Java 桌面開發核心技能。本文通過一個簡易計算機案例,層層遞進展示三種事件註冊寫法,並分析優缺點與適用場景。
介面包含:下拉框選擇運算符(+/-)、兩個輸入框、結果顯示框、「計算」與「清空」按鈕。
// 為下拉框註冊動作監聽器
comboBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (comboBox.getSelectedIndex() == 0) {
operatorLabel.setText(" + ");
} else {
operatorLabel.setText(" - ");
}
}
});
// 為「計算」按鈕註冊
doneButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// 根據運算符執行加減邏輯...
}
});
優點:就地定義,封裝性好。
缺點:元件多時程式碼膨脹,難以復用邏輯。
// 定義獨立監聽器
class ClearActionListener implements ActionListener {
private JTextField operand1, operand2, result;
public ClearActionListener(JTextField o1, JTextField o2, JTextField res) {
this.operand1 = o1; this.operand2 = o2; this.result = res;
}
@Override
public void actionPerformed(ActionEvent e) {
operand1.setText("");
operand2.setText("");
result.setText("");
}
}
// 使用:多個按鈕可共享同一實例
ClearActionListener clearListener = new ClearActionListener(field1, field2, resultField);
clearButton.addActionListener(clearListener);
anotherClearButton.addActionListener(clearListener); // 復用
優點:邏輯集中、可復用、便於單元測試。
缺點:類數量增加,構造函數傳參稍顯繁瑣。
public class CalculatorFrame extends JFrame implements ActionListener {
// ... 元件宣告 ...
@Override
public void actionPerformed(ActionEvent e) {
Object src = e.getSource();
if (src == comboBox) {
// 切換運算符
} else if (src == doneButton) {
// 計算邏輯
} else if (src == clearButton) {
// 清空邏輯
}
}
// 註冊時直接傳 this
comboBox.addActionListener(this);
doneButton.addActionListener(this);
clearButton.addActionListener(this);
}
優點:所有事件集中在一個方法,維護方便。
缺點:類職責過重,違反單一職責原則;大型表單會導致 actionPerformed 膨脹難讀。
| 場景 | 推薦寫法 |
|---|---|
| 邏輯簡單、元件少(<5) | 匿名內部類 / Lambda (Java 8+) |
| 多元件共享同一行為 | 獨立監聽器類 |
| 中型表單、邏輯相關緊密 | 統一分派 或 控制器模式 |
| 大型專案 | MVC/MVP 架構,事件委派給 Controller |
doneButton.addActionListener(e -> calculate());
clearButton.addActionListener(e -> clearFields());
comboBox.addActionListener(e -> updateOperatorLabel());