我使用Scala和Publisher
特征来监听我的数据组件的更改并发布/更新显示以摆动UI组件(如this)
我最近重写了我的程序以使用Javafx2
和Scala
,我无法使用最近的绑定项目Scalafx
,因为只有部分程序切换到javafx(这是嵌入摇摆JFrame)。
我可以在scala中使用哪种最佳语法来获得基于scala.swing Publisher
特征的相同(或类似)行为?
您是否有一些链接或简单示例来说明此方法?
答案 0 :(得分:1)
目前我建议的是重复使用实现发布/反应系统的scala.swing
模式。
可以从旧scala.swing
存储库中的scala.swing.Component获取示例。
我们的想法是为需要发布事件的所有 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
库的人来说可能是一个非常有趣的库。