Reputation: 553
I'm using Scala and Publisher
trait to listen the change on my data component and publish/update display to swing UI component (like this)
I recently rewrite my program to use Javafx2
and Scala
, and i cannot use the recent binding project Scalafx
, because only some of part of my program switch to javafx (which is embedded into swing JFrame).
What is the best syntax i can use in scala to have the same (or similar) behaviour based on scala.swing Publisher
trait ?
Do you have some link or simple example to illustrate this method ?
Upvotes: 2
Views: 600
Reputation: 7373
What I can suggest at the moment is reusing the patterns from scala.swing
that implemented the Publish/React system.
An example can be taken from the scala.swing.Component in the old scala.swing
repository.
The idea is to create the possibly most generic wrapper for all javafx classes that need to publish events, and implicitly convert these classes to this wrapper.
The wrapper would define the logic for bridging events from javafx listeners to the publish/react system.
An example code would look like this, and is based on the aforementioned scala.swing
code
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)
...
}
}
}
}
Then you can support reacting in your components as you do with scala.swing
class MyComponent {
import scala.fx.react.ScalaFxReactive._
listenTo(node)
reactions += {
...
}
}
The code is to be taken as a rough sketch and will not compile as it is. It points in a possible direction, but the complete solution could be an interesting enough library for people that, like you, need to progressively bridge legacy scala.swing
application to the javafx
library.
Upvotes: 1