Swing 組件為 JavaBeans,擁有 addXXXListener/removeXXXListener 方法。傳統方式需實現監聽器介面(常用匿名內部類)。範例:按鈕點擊打印「Hello, World!」產生兩個 .class 文件(主類 + 匿名類 $1)。
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("Hello, World!");
}
});
java.beans.EventHandler 利用反射動態創建監聽器實例,無需實現介面、無額外 .class 文件。提供三個靜態 create() 重載:
create(Class listenerInterface, Object target, String action)
create(Class listenerInterface, Object target, String action, String eventPropertyName)
create(Class listenerInterface, Object target, String action, String eventPropertyName, String listenerMethodName)
最簡單:監聽器所有方法均調用目標對象的無參方法 action。需強制轉型,目標方法必須公共無參。範例:
button.addActionListener((ActionListener)EventHandler.create(
ActionListener.class, this, "print"));
public void print() { System.out.println("Hello, World!"); }
第四參數 eventPropertyName 指定事件屬性,第三參數 action 為目標可寫屬性名。事件發生時,以事件屬性值設置目標屬性。範例:文本框回車時,標籤文字設為文本框內容:
text.addActionListener((ActionListener)EventHandler.create(
ActionListener.class, label, "text", "source.text"));
等效於 label.setText(((JTextField)e.getSource()).getText())。
第五參數 listenerMethodName 指定針對哪個監聽器方法調用 action。可為同一監聽器介面不同方法綁定不同操作。範例:滑鼠按下/釋放分別調用 pressed(Point)/released(Point):
contentPane.addMouseListener((MouseListener)EventHandler.create(
MouseListener.class, this, "pressed", "point", "mousePressed"));
contentPane.addMouseListener((MouseListener)EventHandler.create(
MouseListener.class, this, "released", "point", "mouseReleased"));
public void pressed(Point p) { System.out.println("Pressed at: " + p); }
public void released(Point p) { System.out.println("Released at: " + p); }
參數 point 為事件屬性,若方法無參則傳 null。此例為演示分別添加兩個監聽器,實際可合併。
EventHandler 利用反射動態代理,減少樣板代碼、無額外類文件。性能稍遜(反射開銷),要求目標方法公共。風格選擇:IDE 生成代碼可保留,手寫代碼可簡化。