SWT ウィジェットを使用して Java アプリケーションを作成しています。特定のイベントが発生したときに特定のウィジェットの状態を更新したいと考えています (たとえば、データ モデルの状態の更新)。
Cocoa の NSNotificationCenter に似たものが Java にあり、オブジェクトを登録して通知イベントをリッスンし、それらに応答したり、他のオブジェクトに通知を「起動」させたりできますか?
SWT ウィジェットを使用して Java アプリケーションを作成しています。特定のイベントが発生したときに特定のウィジェットの状態を更新したいと考えています (たとえば、データ モデルの状態の更新)。
Cocoa の NSNotificationCenter に似たものが Java にあり、オブジェクトを登録して通知イベントをリッスンし、それらに応答したり、他のオブジェクトに通知を「起動」させたりできますか?
わかりました、たとえば、ローダーがスキャンを開始したとき、およびスキャンを終了したときに、プログラムの一部に通知したいとします (ローダーが何であるか、またはスキャンが何であるかについて心配する必要はありません。これらは次の例です)。最後の仕事から転がっているいくつかのコード)。インターフェイスを定義し、それを「ScanListener」と呼びます。
public interface ScanListener
{
public void scanStarted();
public void scanCompleted();
}
ローダーは、他のコードがコールバックに登録するためのメソッドを定義します。
public void addScanListener(ScanListener listener)
{
listeners.add(listener);
}
ローダーは、スキャンを開始すると、次のコードを実行します
for (ScanListener listener : listeners)
{
listener.scanStarted();
}
終了すると、listener.scanCompleted(); で同じことを行います。
これらのイベントの通知が必要なコードは、そのインターフェイスを (それ自体または内部クラスで) 実装し、「loader.addScanListener(this)」を呼び出します。その scanStarted() および scanCompleted() メソッドは、適切なタイミングで呼び出されます。引数を取ったり、結果を返したりするコールバックでもこれを行うことができます。それはすべてあなた次第です。
デフォルトの NSNotificationCenter に相当する、Java でイベントをディスパッチする既存のプロセスごとのサービスはありません。Java では、イベントのタイプは、文字列を使用するのではなく、特定のタイプのイベント オブジェクトによって指定されます (これは、通知メソッドがそのタイプに依存することも意味します)。ジェネリックの前は、タイプセーフでもある一般的なイベント ディスパッチャーとレシーバーを作成することは実際には不可能です (AWT および Spring ライブラリでの *Event クラスと *EventListener インターフェイスの急増を目の当たりにしてください)。
イベント派遣のための施設がいくつかあります。ポールが述べたように、java.util.Observable
あなたが指摘したように、サブクラス化が必要な があります。もありjava.beans.PropertyChangeSupport
、状況によっては便利です。
自分で書くこともできます。のソースPropertyChangeSupport
は openjdk で入手できる可能性が高く、放棄されたApache Commons Eventプロジェクトを見ることができます。必要に応じて、スレッド化、シリアライゼーション、メモリ リーク (確実に登録解除するか弱参照を使用する)、および同時変更 (リスナーが自分自身を登録解除することを決定するため、リスナーのリストのコピーを反復処理する) などについて心配する必要がある場合があります。変化に応じて)。
ジェネリックが Java に存在するようになったので、ジェネリック イベント ディスパッチ ライブラリが可能になります。しかし、私は遭遇していません。誰?
実際には、Javaに組み込まれている機能があり、まさにあなたが望むことを実行しますが、それはあなたが考えたものではなく、正直なところ、あなたが望むものには少し重いでしょう。
とはいえ、それは存在します。
JMXです。
MBeanを作成すると、他の人がそれらのMBeanからのイベントに登録できます。その後、MBeanは通知を送信できます。
私は個人的にこの場合にそれを使用することを検討しませんでした(私は自分自身を打ち負かすだけです)が、施設はそこにあり、明確に定義され、文書化されています。
Javaではありませんが、IPythonプロジェクトには、Javaバージョンのテンプレートとして使用できるPythonで記述された通知センターがあります。
Java では、これはプロバイダーがそのリスナーに通知を送信することになります。しかし Java では、Cocoa の NSNotification で得られる疎結合は提供されません。これは、Java ではプロバイダーとサブスクライバーが相互に参照する必要があるためです。「Learn Objective-C for Java Developers」のこの第 18 章と比較してください。
JavaでのIOS NSNotificationCenterの
実装があります。
ソースコードは次の場所にあります:
この Github プロジェクト