torutkのブログ

ソフトウェア・エンジニアのブログ

EventBus(続)

d:id:torutk:20110407の続きです。

EventBusのライブラリ設定

ダウンロードしたバイナリのjarファイル(eventbus-1.4.jar)をコンパイルおよび実行時のクラスパスに通します。

NetBeansの場合は、[ツール]メニュー>[ライブラリ]でライブラリマネージャーダイアログを開き、[新規ライブラリ]ボタンを押し、名前を"EventBus"にします。[クラスパス]タブでeventbus-1.4.jarを指定、[ソース]タブでeventbus-1.4-sources.jarを指定、[Javadoc]タブでeventbus-1.4-javadoc.jarを指定し[了解]ボタンを押します。
EventBusを使用するプロジェクトのプロパティーを開き、ライブラリのコンパイルにEventBusのライブラリを追加します。

EventBusを使ったイベントの発行・受領の方法

EventBusには、標準で2つのイベントサービス実装が用意されています。

  1. SwingEventService
  2. ThreadSafeEventService

前者は、イベント発行をどのスレッド上で実行したとしても、イベント受領はSwing(AWT)のEDT(Event Dispatch Thread)で実行されるようになっているため、イベントによってGUIを変更するプログラムに向いた実装です。
後者は、イベント発行を実行したスレッドと同じスレッドでイベント受領を実行するようになっているため、Swing以外のコンポーネント間の通知に向いた実装です。

ここで、イベント発行すると、新たな別スレッドでイベント受領を実行するような実装も欲しいことがありますが、EventBus 1.4では搭載されていないので、自前でEventServiceを用意することになります。

イベントの受領

イベントを受領する方法として大きく2つあります。

  1. イベントオブジェクトの型を明示してその型のイベントが発行されたら受領する
  2. 文字列のトピックを明示して、トピックに合致したイベントが発行されたら受領する

今回は最初の型で指定する方法を実装してみます。この方法でイベントを受け取るときは、EventBusのAPIとして次の2つの実装手段が用意されています。

  1. EventSubscriberインタフェースを実装する
  2. EventSubscriverアノテーションを指定する

ここで、SimpleEvent型のイベントを受領するSimpleSubscriberの実装を比べてみます。

// EventSubscriverインタフェースを実装しSimpleEvent型のイベントを受領する
import org.bushe.swing.event.EventSubscriber;

public class SimpleSubscriber implements EventSubscriber<SimpleEvent> {
    @Override
    public void onEvent(SimpleEvent event) {
        // イベント受領処理
    }
}
// EventSubscriverアノテーションを指定しSimpleEvent型のイベントを受領する
import org.bushe.swing.event.annotation.EventSubscriber;

public class SimpleAnnotatedSubscriber {
    @EventSubscriber
    public void handleSimpleEvent(SimpleEvent event) {
        // イベント受領処理
    }
}

アノテーションを指定する場合、アノテーションを付けた型のオブジェクトを最初にEventBusのAnnotationProcessorに処理させる必要があります。

import org.bushe.swing.event.annotation.AnnotationProcessor;

public class SimpePubSub {
    public static void main(String[] args) {
        SimpleAnnotationSubscriber sub = new SimpleAnnotationSubscriber();
        AnnotationProcessor.process(sub);
        :
    }
}

SimpleAnnotationSubscriberのコンストラクタに記述してもよいのですが、コンストラクタの中でthisを逸出されるのはよろしくないコーディングなので、上記のようにしました。

インタフェースかアノテーションか、については、1つのクラスで複数の異なる型のイベントを受ける場合はアノテーションにするのがよいと思います。

イベントの発行

EventBusは、デフォルトでは SwingEventService を使用します。SwingEventServiceを使用する場合は、以下のようにイベントを発行します。

import org.bushe.swing.event.EventBus;

public class SimplePublisher {
    :
    void send() {
        SimpleEvent event = new SimpleEvent("hello");
        EventBus.publish(event);
    }
}