2012-10-30 73 views
2

我使用Scala和Publisher特質聽我的數據組件的變化和發佈/更新顯示擺動的UI組件(如this如何添加監聽器的JavaFX UI組件使用Scala

我最近重寫我的程序使用Javafx2Scala,我不能使用近期綁定項目Scalafx,因爲只有我的一些程序切換到JavaFX的(被嵌入擺動的JFrame)的一部分。

什麼是我可以在Scala中使用基於scala.swing Publisher性狀具有相同(或相似)的行爲最好的語法?

你有一些鏈接或簡單的例子來說明這種方法嗎?

回答

1

我當時可以建議被重用從scala.swing該實施發佈/陣營系統的模式。 可以從舊scala.swing存儲庫中的scala.swing.Component中獲取示例。

這個想法是爲所有需要發佈事件的類創建可能最通用的包裝器,並隱式地將這些類轉換爲此包裝器。

該包裝將聽衆定義邏輯用於橋接從事件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庫。