3

Google Guava EventBusExplainedページで、次のように言っていることがわかりません。

一般的なイベントのスーパータイプ (EventObject や Object など) をリッスンするには...
...従来の Java イベントでは: 簡単ではありません。
...EventBus を使用: イベントは任意のスーパータイプのリスナーに自動的にディスパッチされ、インターフェイス タイプのリスナーまたはオブジェクトの「ワイルドカード リスナー」を許可します。

  1. 一般的なイベントのスーパータイプをリッスンするとはどういう意味ですか?
  2. 彼らが EventObject について言及するとき、彼らは java.util.EventObject について話しているのでしょうか?
  3. 「インターフェースタイプのリスナーまたはオブジェクトの「ワイルドカードリスナー」」を許可するとはどういう意味ですか?
4

2 に答える 2

6

EventBusこれは、グアバのクラスが克服できるメソッドのオーバーロードとインターフェースの制限に関係しています。

インターフェイスについては、次のシナリオを検討してください。

複数の形式の入力に対して呼び出される同じコードがあります。たとえば、マウス イベント、キー イベント、およびフォーカス イベントをリッスンするリスナーですが、すべてのメソッドは同じことを行います: ソースを再描画します。これは、私のコードが次のようになることを意味します。

public class BunchOfListeners implements MouseListener, KeyListener, FocusListener {

    @Override
    public void focusGained(FocusEvent e) {
        doSomething(e);
    }

    @Override
    public void focusLost(FocusEvent e) {
        doSomething(e);
    }

    @Override
    public void keyTyped(KeyEvent e) {
        doSomething(e);
    }

    @Override
    public void keyPressed(KeyEvent e) {
        doSomething(e);
    }

    @Override
    public void keyReleased(KeyEvent e) {
        doSomething(e);
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        doSomething(e);
    }

    @Override
    public void mousePressed(MouseEvent e) {
        doSomething(e);
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        doSomething(e);
    }

    @Override
    public void mouseEntered(MouseEvent e) {
        doSomething(e);
    }

    @Override
    public void mouseExited(MouseEvent e) {
        doSomething(e);
    }

    public void doSomething(EventObject e) {
        ((Component) e.getSource()).repaint();
    }
}

これがどれほど醜いことに気づきますか?これには 10 の異なる方法がありますが、最終的には、イベントからソースを取得することだけが重要です (EventObjectちなみに、これが で指定されているため、例でそれを使用しました) repaint

Guava のを使用EventBusすると、これは非常に簡単になります。クラスで必要なのは 1 つのメソッドだけです。GuavaIsAwesome ComponentRepainter

public class ComponentRepainter {

    @Subscribe
    public void doSomething(EventObject e) {
        ((Component) e.getSource()).repaint();
    }
}

これを に登録し、EventBus後で発火すると、次のようMouseEventになります。

EventBus eventBus = ... ;
eventBus.register(new ComponentRepainter());

以降:

MouseEvent e = ... ;
eventBus.post(e);

doSomethingこれにより、メソッドが呼び出されます。これは、パラメーターの を持つメソッドだけでなく、から割り当て可能なパラメーターを持つすべてのメソッドにもイベントComponentRepainterが発生するためです。つまり、extendsであるため、Guavaはそれを受け入れるものすべてに渡します。acceptを作成すると、 に投稿されたすべてのイベントを取得でき、一種のグローバル リスナーになります ( Java ではすべてが を拡張するため)。@SubscribeMouseEventMouseEventMouseEventEventObjectEventBusEventObjectdoSomethingObjectEventBusObject

同じことがインターフェースにも当てはまります。EventBus何らかのインターフェースの具体的な実装を渡すと、@Subscribe(具体的な型ではなく) そのインターフェースを使用するメソッドが呼び出されます。それははるかに柔軟で、「10 の役に立たない方法」アプローチを克服します。

于 2012-11-17T00:23:36.850 に答える
3

2 つのイベント ソースがあるとします。1 つは type の発生イベントでFooEvent、もう 1 つはtype の発生イベントですBarEvent。共通のスーパークラスFooEventBarEvent拡張する (または共通のインターフェースを実装する) としMyEventます。

EventBus を使用すると、 type のイベントをリッスンでき、とMyEventが通知されます。どちらもこの共通のスーパータイプ を拡張しているためです。FooEventBarEventMyEvent

type のイベントをリッスンするjava.lang.Objectと、すべてのイベントが通知されます。これは、Java のすべてのクラスが Object を拡張するためです。これはワイルドカード リスナーです。すべてをリッスンします。

于 2012-11-17T00:08:06.373 に答える