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のインスタンスを直接扱うことはありません。その代わりに、EventHandlerのcreateメソッドを使って、指定されたリスナー・インタフェースを実装するオブジェクトを作成します。このリスナー・オブジェクトは、内部で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の場合は、どちらのメソッドも適しているため、呼び出されるメソッドは不定です。そのため、オーバーロードされたメソッドをターゲットにしないことをお薦めします。Proxy, EventObject| コンストラクタと説明 |
|---|
EventHandler(Object target, String action, String eventPropertyName, String listenerMethodName)
新しい
EventHandlerオブジェクトを作成します(このコンストラクタを直接呼び出すのではなく、いずれかのcreateメソッドを使用するのが一般的)。 |
| 修飾子と型 | メソッドと説明 |
|---|---|
static <T> T |
create(Class<T> listenerInterface, Object target, String action)
リスナー・インタフェース内のすべてのメソッドがハンドラの
actionをtargetに適用するようなlistenerInterface実装を作成します。 |
static <T> T |
create(Class<T> listenerInterface, Object target, String action, String eventPropertyName)
/** すべてのメソッドが、イベント式
eventPropertyNameの値を文中のfinalメソッドであるaction (targetに適用される)に渡すようなlistenerInterface実装を作成します。 |
static <T> T |
create(Class<T> listenerInterface, Object target, String action, String eventPropertyName, String listenerMethodName)
listenerMethodNameという名前のメソッドが、イベント式eventPropertyNameの値を文中のfinalメソッドであるaction (targetに適用される)に渡すようなlistenerInterface実装を作成します。 |
String |
getAction()
このイベント・ハンドラによって設定されるターゲットの書込み可能なプロパティ、またはこのイベントがターゲット上で呼び出すメソッドの名前を返します。
|
String |
getEventPropertyName()
ターゲットに適用されるアクションで使用されるイベントのプロパティを返します。
|
String |
getListenerMethodName()
アクションをトリガーするメソッドの名前を返します。
|
Object |
getTarget()
このイベント・ハンドラがメッセージの送信先とするオブジェクトを返します。
|
Object |
invoke(Object proxy, Method method, Object[] arguments)
イベントから適切なプロパティ値を抽出し、この
EventHandlerに関連付けられているアクションに渡します。 |
@ConstructorProperties(value={"target","action","eventPropertyName","listenerMethodName"}) public EventHandler(Object target, String action, String eventPropertyName, String listenerMethodName)
EventHandlerオブジェクトを作成します(このコンストラクタを直接呼び出すのではなく、いずれかのcreateメソッドを使用するのが一般的)。eventPropertyNameおよびlistenerMethodNameパラメータの詳細は、the general version of createを参照してください。target - アクションを実行するオブジェクトaction - ターゲット上の(修飾されている可能性がある)プロパティまたはメソッドの名前eventPropertyName - 受信イベントの読取り可能なプロパティの(修飾されている可能性がある)名前listenerMethodName - アクションをトリガーするべきリスナー・インタフェース内のメソッドの名前NullPointerException - targetがnullである場合NullPointerException - actionがnullである場合EventHandler, create(Class, Object, String, String, String), getTarget(), getAction(), getEventPropertyName(), getListenerMethodName()public Object getTarget()
EventHandler(Object, String, String, String)public String getAction()
EventHandler(Object, String, String, String)public String getEventPropertyName()
EventHandler(Object, String, String, String)public String getListenerMethodName()
nullは、リスナー・インタフェース内のすべてのメソッドがアクションをトリガーすることを表します。EventHandler(Object, String, String, String)public Object invoke(Object proxy, Method method, Object[] arguments)
EventHandlerに関連付けられているアクションに渡します。invoke、インタフェース: InvocationHandlerproxy - プロキシ・オブジェクトmethod - リスナー・インタフェース内のメソッドarguments - プロキシ・インスタンスでのメソッド呼出し時に渡される引数値を格納するオブジェクト配列。インタフェース・メソッドが引数を取らない場合、nullとなる。プリミティブ型引数はjava.lang.Integerまたはjava.lang.Booleanのような適切なプリミティブ型ラッパー・クラスのインスタンスにラップされる。EventHandlerpublic static <T> T create(Class<T> listenerInterface, Object target, String action)
actionをtargetに適用するようなlistenerInterface実装を作成します。このメソッドは、null値をとるeventPropertyNameとlistenerMethodNameの両方を持つ、ほかのより一般的な実装のcreateメソッドを呼び出すことによって実装されます。actionパラメータの詳細は、the general version of createを参照してください。
次に、dialog.show()を使って、JDialogを表示するActionListenerを作成する例を示します。
EventHandler.create(ActionListener.class, dialog, "show")
T - 作成する型listenerInterface - プロキシの作成対象となるリスナー・インタフェースtarget - アクションを実行するオブジェクトaction - ターゲット上の(修飾されている可能性がある)プロパティまたはメソッドの名前listenerInterfaceを実装するオブジェクトNullPointerException - listenerInterfaceがnullである場合NullPointerException - targetがnullである場合NullPointerException - actionがnullである場合create(Class, Object, String, String)public static <T> T create(Class<T> listenerInterface, Object target, String action, String eventPropertyName)
eventPropertyNameの値を文中のfinalメソッドであるaction (targetに適用される)に渡すようなlistenerInterface実装を作成します。このメソッドは、null値をとるlistenerMethodNameを持つ、より一般的な実装のcreateメソッドを呼び出すことによって実装されます。actionおよびeventPropertyNameパラメータの詳細は、the general version of createを参照してください。
次のコードを使って、JLabelのテキストを受信イベントのJTextFieldソースのテキスト値に設定するActionListenerを作成できます。
これは次のコードと等価です。EventHandler.create(ActionListener.class, label, "text", "source.text");
//Equivalent code using an inner class instead of EventHandler.
new ActionListener() {
public void actionPerformed(ActionEvent event) {
label.setText(((JTextField)(event.getSource())).getText());
}
};
T - 作成する型listenerInterface - プロキシの作成対象となるリスナー・インタフェースtarget - アクションを実行するオブジェクトaction - ターゲット上の(修飾されている可能性がある)プロパティまたはメソッドの名前eventPropertyName - 受信イベントの読取り可能なプロパティの(修飾されている可能性がある)名前listenerInterfaceを実装するオブジェクトNullPointerException - listenerInterfaceがnullである場合NullPointerException - targetがnullである場合NullPointerException - actionがnullである場合create(Class, Object, String, String, String)public static <T> T create(Class<T> listenerInterface, Object target, String action, String eventPropertyName, String listenerMethodName)
listenerMethodNameという名前のメソッドが、イベント式eventPropertyNameの値を文中のfinalメソッドであるaction (targetに適用される)に渡すようなlistenerInterface実装を作成します。その他のリスナー・メソッドは、何も処理を行いません。
eventPropertyName文字列は、ターゲット・メソッドに渡される受信イベント・オブジェクトから値を抽出するために使用されます。一般に、ターゲット・メソッドは引数を取らないため、eventPropertyNameでnull値を使用するようにしてください。また、受信イベント・オブジェクトをターゲット・メソッドに直接渡すには、空の文字列を使用します。eventPropertyName文字列の形式は、メソッドまたはプロパティのシーケンスで、それぞれのメソッドまたはプロパティは、着信するイベント・オブジェクトから始まる直前のメソッドによって返される値に適用されます。構文は次のとおりです。propertyName{.propertyName}*ここでpropertyNameはメソッドまたはプロパティに一致します。たとえばpointプロパティをMouseEventから抽出するには、"point"または"getPoint"をeventPropertyNameとして使用できます。textプロパティをJLabelソースを持つMouseEventから抽出するには、"source.text"、"getSource.text"、"getSource.getText"または"source.getText"をeventPropertyNameとして使用します。メソッドが見つからない場合、またはメソッドの呼出しで例外が生成された場合は、ディスパッチ時にRuntimeExceptionがスローされます。たとえば受信イベント・オブジェクトがnullで、eventPropertyNameがnullでも空でもない場合は、RuntimeExceptionがスローされます。
action引数の形式はeventPropertyName引数の形式と同じで、最後のプロパティ名はメソッド名または書込み可能なプロパティを表します。
listenerMethodNameがnullの場合は、インタフェース内のすべてのメソッドが、target上で実行されるactionをトリガーします。
たとえば、マウス・ボタンを押すたびにターゲット・オブジェクトのoriginプロパティを受信するMouseEventの場所(mouseEvent.getPoint()の値)に設定するMouseListenerを作成したい場合は、次のように記述します。
これは、EventHandler.create(MouseListener.class, target, "origin", "point", "mousePressed");
mousePressedを除くすべてのメソッドが操作不能であるMouseListenerの記述と同じです。
//Equivalent code using an inner class instead of EventHandler.
new MouseAdapter() {
public void mousePressed(MouseEvent e) {
target.setOrigin(e.getPoint());
}
};
T - 作成する型listenerInterface - プロキシの作成対象となるリスナー・インタフェースtarget - アクションを実行するオブジェクトaction - ターゲット上の(修飾されている可能性がある)プロパティまたはメソッドの名前eventPropertyName - 受信イベントの読取り可能なプロパティの(修飾されている可能性がある)名前listenerMethodName - アクションをトリガーするべきリスナー・インタフェース内のメソッドの名前listenerInterfaceを実装するオブジェクトNullPointerException - listenerInterfaceがnullである場合NullPointerException - targetがnullである場合NullPointerException - actionがnullである場合EventHandler バグまたは機能を送信
詳細なAPIリファレンスおよび開発者ドキュメントについては、Java SEのドキュメントを参照してください。そのドキュメントには、概念的な概要、用語の定義、回避方法、有効なコード例などの、開発者を対象にしたより詳細な説明が含まれています。
Copyright© 1993, 2014, Oracle and/or its affiliates. All rights reserved.