ルービック キューブの Scala アプリケーションに MVC デザイン パターンを実装しようとしています。
Java ではActionListener
、コントローラー クラスのリスナーを使用してボタンに を追加することでこれを行います。Scala では、これが非常に難しいことがわかりました。これを行う方法の例を誰か教えてもらえますか?
ルービック キューブの Scala アプリケーションに MVC デザイン パターンを実装しようとしています。
Java ではActionListener
、コントローラー クラスのリスナーを使用してボタンに を追加することでこれを行います。Scala では、これが非常に難しいことがわかりました。これを行う方法の例を誰か教えてもらえますか?
もちろん、Java で行ったのとまったく同じ方法で実行できます。ただし、Scala を使用すると、Java Swing クラスのラッパーのセットを提供する Scala スイング ライブラリを使用してこれを行うこともできます。パブリッシャーとリアクターの概念を使用して、イベントを観察し、反応します。サンプルを含むライブラリの設計に関する紹介は、ここで見つけることができます。
Publisher
トレイトは、登録されているすべての Reactor にイベントについて通知するメソッドを定義しますpublish(e: Event)
。このトレイトを拡張するだけで任意のクラスをパブリッシャーにすることができ、publish メソッドを呼び出してイベントをパブリッシュできます。def listenTo(ps: Publisher)
メソッドを使用してリアクタを登録し、 を使用して登録を解除できますdef deafTo(ps: Publisher)
。PartialFunction[Event, Unit]
パブリッシャーをリッスンする場合、次のように type のリアクションを追加することで、このパブリッシャーからのイベントに反応できます。
class MyComponent {
listenTo(publisher)
reactions += {
case e: MyEvent => println("Got event " + e)
}
}
これは、Scala-swing を使用した (完全に不完全な) コードで、MVC パターンでこれを使用する方法についてのアイデアを提供してくれることを願っています。また、ライブラリの一部であるテスト パッケージをチェックアウトすることもできます。ここでは、多数の例を見つけることができます。
import scala.swing
import scala.swing.event._
case object MyBusinessEvent extends Event
class MyController extends Publisher {
val form = new MyForm
listenTo(form)
reactions += {
case MyBusinessEvent => //handle event code here
}
}
class MyForm extends Publisher {
val ui = new GridBagPanel {
val c = new Constraints
.... more code here
}
val button1 = new Button("Button 1")
//add button to panel
listenTo(button1)
reactions += {
case ButtonClicked(_) => publish(MyBusinessEvent)
}
}
フォーム内のlistenTo(button1)
メソッドは、ボタン イベントについてフォームに通知します。この場合ButtonClicked
、scala-swing ライブラリで定義されているイベントであるイベントに反応します。このサンプルでは、フォームはボタン イベントをカスタム定義のビジネス イベントに再発行するだけです。コントローラ クラスはフォームをリッスンし、ビジネス イベントに適切な方法で反応できます。