モジュール java.desktop
パッケージ java.beans

クラスEventHandler

java.lang.Object
java.beans.EventHandler
すべての実装されたインタフェース:
InvocationHandler

public class EventHandler extends Object implements InvocationHandler
EventHandlerクラスは、受信イベント・オブジェクトとターゲット・オブジェクトを含んだ単純な文を実行するメソッドを持つ、イベント・リスナーの動的生成をサポートします。

EventHandlerクラスは、開発者がBean間の接続を確立するために使用する、アプリケーション・ビルダーのような対話型ツールで使用されます。 通常、接続は、ユーザー・インタフェースBean (イベント・ソース)からアプリケーション・ロジックBean (ターゲット)に向けて確立されます。 そのなかでも、ユーザー・インタフェースからアプリケーション・ロジックを隔離するような接続は特に効果的です。 たとえば、JCheckBoxとブール値を受け付けるメソッドを接続するEventHandlerは、チェックボックスの状態を抽出し、これを直接メソッドに渡すことによって、メソッドをユーザー・インタフェース層から隔離することができます。

ユーザー・インタフェースを使ったイベントの処理方法としてより一般的なのは、内部クラスを使用する方法です。 EventHandlerクラスで処理できるのは、内部クラスで処理できるイベントのサブセットに過ぎません。 ただし、長期持続スキームでは、内部クラスよりもEventHandlerのほうが優れています。 また、同じインタフェースを実装している大規模なアプリケーションでEventHandlerを繰返し利用すれば、ディスクやアプリケーションのメモリー・フットプリントを削減できます。

EventHandlerで作成されたリスナーのフットプリントが小さいのは、EventHandlerの依存先のProxyクラスが同じインタフェースの実装を共有しているからです。 たとえば、EventHandler createメソッドを使用してアプリケーション内のすべてのActionListenerを作成する場合、すべてのアクション・リスナーは単一のクラス(Proxyクラスによって作成されたもの)のインスタンスになります。 通常、Proxyクラスのリスナーを使用する場合は、リスナー型 (インタフェース)ごとにリスナー・クラスを1つずつ作成する必要があります。しかし、内部クラスを使用する方法では、リスナー (インタフェースを実装するオブジェクト)ごとにクラスを1つずつ作成するだけで済みます。

通常、EventHandlerのインスタンスを直接扱うことはありません。 その代わりに、EventHandlercreateメソッドを使って、指定されたリスナー・インタフェースを実装するオブジェクトを作成します。 このリスナー・オブジェクトは、内部でEventHandlerオブジェクトを使って、イベントに関する情報、イベント発生時にメッセージを送信されるオブジェクト、送信されるメッセージ(メソッド)、およびメソッドの引数をカプセル化します。 次のセクションでは、例を使って、createメソッドによるリスナー・オブジェクトの作成方法について説明します。

イベント・ハンドラの使用例

ターゲット・オブジェクト上のメソッドを引数なしで呼び出すリスナーをインストールするというのが、もっとも単純なEventHandlerの利用方法です。 次の例では、javax.swing.JFrameのインスタンス上のtoFrontメソッドを呼び出すActionListenerを作成します。
myButton.addActionListener(
    (ActionListener)EventHandler.create(ActionListener.class, frame, "toFront"));
myButtonを押すと、frame.toFront()文が実行されます。 コンパイル時の型保証を追加しても、同じ結果が得られます。このためには、ActionListenerインタフェースの新しい実装を定義し、そのインスタンスをボタンに追加します。
//Equivalent code using an inner class instead of EventHandler.
myButton.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        frame.toFront();
    }
});
次にEventHandlerの単純な利用方法として、リスナー・インタフェース(通常はイベント・オブジェクト)内のメソッドの最初の引数からプロパティ値を抽出し、これを使ってターゲット・オブジェクト内のプロパティ値を設定する例を紹介します。 この例では、ターゲット(myButton)オブジェクトのnextFocusableComponentプロパティをイベントのsourceプロパティの値に設定するActionListenerを作成します。
EventHandler.create(ActionListener.class, myButton, "nextFocusableComponent", "source")
これは、次の内部クラス実装に対応しています。
//Equivalent code using an inner class instead of EventHandler.
new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        myButton.setNextFocusableComponent((Component)e.getSource());
    }
}
受信イベント・オブジェクトをターゲット・アクションに渡すだけのEventHandlerを作成することもできます。 4番目のEventHandler.create引数が空の文字列である場合、次のようにしてイベントが渡されます。
EventHandler.create(ActionListener.class, target, "doActionEvent", "")
これは、次の内部クラス実装に対応しています。
//Equivalent code using an inner class instead of EventHandler.
new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        target.doActionEvent(e);
    }
}
イベント・オブジェクトのソースからプロパティ値を抽出し、この値をターゲット・オブジェクトのプロパティ値として設定するというのが、おそらくもっとも一般的なEventHandlerの利用方法でしょう。 次の例では、ターゲット・オブジェクトのlabelプロパティをイベントのソースのtextプロパティの値(sourceプロパティの値)に設定するActionListenerを作成します。
EventHandler.create(ActionListener.class, myButton, "label", "source.text")
これは、次の内部クラス実装に対応しています。
//Equivalent code using an inner class instead of EventHandler.
new ActionListener {
    public void actionPerformed(ActionEvent e) {
        myButton.setLabel(((JTextField)e.getSource()).getText());
    }
}
イベント・プロパティは、ピリオド(.)で区切られた任意の数のプロパティ接頭辞によって修飾されます。 ピリオドの前に表示される完全指定名は、イベント・オブジェクトに適用されるプロパティ(左から順に適用)の名前として扱われます。

たとえば、次のようなアクション・リスナーがあります。

EventHandler.create(ActionListener.class, target, "a", "b.c.d")
このアクション・リスナーは、次の内部クラスとして書き込まれます(すべてのプロパティが正規の取得メソッドを持ち、適切な型を返すものと想定)。
//Equivalent code using an inner class instead of EventHandler.
new ActionListener {
    public void actionPerformed(ActionEvent e) {
        target.setA(e.getB().getC().isD());
    }
}
ターゲット・プロパティは、ピリオド(.)で区切られた任意の数のプロパティ接頭辞によっても修飾されます。 たとえば、次のようなアクション・リスナーがあります。
   EventHandler.create(ActionListener.class, target, "a.b", "c.d")
 
このアクション・リスナーは、次の内部クラスとして書き込まれます(すべてのプロパティが正規の取得メソッドを持ち、適切な型を返すものと想定)。
   //Equivalent code using an inner class instead of EventHandler.
   new ActionListener {
     public void actionPerformed(ActionEvent e) {
         target.getA().setB(e.getC().isD());
    }
}

EventHandlerはメソッドを呼び出す際に最終的にリフレクションに依存するため、オーバーロードされたメソッドをターゲットにしないことをお薦めします。 たとえば、ターゲットが次のように定義されたMyTargetクラスのインスタンスであるとします。

   public class MyTarget {
     public void doIt(String);
     public void doIt(Object);
   }
 
これでdoItメソッドはオーバーロードされます。 EventHandlerはソースに基づいて適切なメソッドを呼び出します。 ソースがnullの場合は、どちらのメソッドも適しているため、呼び出されるメソッドは不定です。 そのため、オーバーロードされたメソッドをターゲットにしないことをお薦めします。

導入されたバージョン:
1.4
関連項目: