現時点で私が提案できるのは、 Publish/Reactシステムscala.swing
を実装したパターンを再利用することです。例は、古い リポジトリのscala.swing.Componentから取得できます。scala.swing
イベントをパブリッシュする必要があるすべてのjavafxクラスに対して、おそらく最も汎用的なラッパーを作成し、これらのクラスをこのラッパーに暗黙的に変換するという考え方です。
ラッパーは、イベントをjavafxリスナーから発行/反応システムにブリッジするためのロジックを定義します。
scala.swing
コード例は次のようになり、前述のコードに基づいています
package scala.fx.react
object ScalaFxReactive {
/*
* Can't say if Node is the best and only class that should be converted.
* You should make implicit publishers from any fx class that supports the
* addEventHandler(someEventType)
*/
implicit def toPublisher(peer: Node): ScalaFxComponentPublisher = new ScalaFxComponentPublisher(peer)
class ScalaFxComponentPublisher(peer: Component) {
/**
* Contains publishers for various mouse events. They are separated for
* efficiency reasons.
*/
object mouse {
/**
* Publishes clicks, presses and releases.
*/
val clicks: Publisher = new LazyPublisher {
lazy val clicked = new EventHandler[MouseEvent] {
def handle(e: MouseEvent) {
/*
*This is the most critical part: you need
* to check if it's possible to create the swing
* event from an fx event, eventually through an
* implicit conversion
*/
publish(new MouseClicked(e))
}
}
def onFirstSubscribe() = peer.setOnMouseClicked(clicked)
def onLastUnsubscribe() = peer.setOnMouseClicked(null)
/*
* probably better:
* def onLastUnsubscribe() = peer.removeEventHandler(MouseEvent.MOUSE_CLICKED)
*/
}
/**
* Publishes enters, exits, moves, and drags.
*/
val moves: Publisher = new LazyPublisher {
lazy val entered = new EventHandler[MouseEvent] {
def handle(e: MouseEvent) {
publish(new MouseEntered(e))
}
}
lazy val exited = new EventHandler[MouseEvent] {
def handle(e: MouseEvent) {
publish(new MouseExited(e))
}
}
/*
* Need implementation
*/
lazy val moved = new EventHandler[MouseEvent] {
...
}
def onFirstSubscribe() {
peer.setOnMouseEntered(entered)
peer.setOnMouseExited(exited)
...
}
def onLastUnsubscribe() {
peer.setOnMouseEntered(null)
peer.setOnMouseExited(null)
...
}
}
}
}
次に、コンポーネントでの反応をサポートできますscala.swing
class MyComponent {
import scala.fx.react.ScalaFxReactive._
listenTo(node)
reactions += {
...
}
}
コードはラフ スケッチと見なされ、そのままではコンパイルされません。それは可能な方向性を示していますが、完全なソリューションは、あなたのようにレガシーscala.swing
アプリケーションをjavafx
ライブラリに段階的に橋渡しする必要がある人々にとって十分に興味深いライブラリになる可能性があります。