S-JIS[2011-04-04] 変更履歴
JavaのSwingでは、イベントを受け取る為のリスナーを用意し、コンポーネントにリスナーを登録する。
すると、コンポーネントでイベントが発生した時にそのリスナーのメソッドが呼ばれる。
(イベント毎に呼ばれるメソッドが異なる)
ScalaのSwingでは、コンポーネントのreactionsに登録した関数でイベントを受け取る。
その関数の中でイベントのパターンマッチを行ってイベント毎の処理を行う。
ボタンが押された時のイベントを受け取る例。
import scala.swing._ import scala.swing.event.ButtonClicked
object EventSample extends SimpleSwingApplication {
override def top = new MainFrame {
title = "サンプル"
contents = new FlowPanel {
contents += new Button("ボタン") {
reactions += {
case ButtonClicked(source) => println(source)
}
}
}
}
}
scala.swing.Buttonでは、ボタンが押下されるとButtonClickedが送られてくる。
scala.swing.Component(LabelやButton等の親クラス)では、マウス(移動・クリック・ホイール)とキー入力のイベントを受け取れるようになっている。
import scala.swing._ import scala.swing.event.MouseClicked
new Label("ラベル") {
listenTo(this.mouse.clicks)
reactions += {
case MouseClicked(source, point, modifiers, clicks, triggersPopup) => println(modifiers, clicks)
}
}
listenToメソッドで、どのイベントを受け取るのか決めるのがポイント。
オブジェクト | イベント | 説明 | イベントの値 | ||
---|---|---|---|---|---|
mouse.clicks |
MouseClicked |
マウスがクリックされた。 | source |
Component |
コンポーネント |
point |
Point |
座標 | |||
modifiers |
Key.Modifiers |
同時に押されていたキーの種類 | |||
clicks |
Int |
クリック回数 | |||
triggersPopup |
Boolean |
||||
MousePressed |
マウスボタンが押された。 | MouseClickedと同じ | |||
MouseReleased |
マウスボタンが離された。 | MouseClickedと同じ | |||
mouse.moves |
MouseEntered |
マウスカーソルがコンポーネント上に入ってきた。 | source |
Component |
コンポーネント |
point |
Point |
座標 | |||
modifiers |
Key.Modifiers |
同時に押されていたキーの種類 | |||
MouseExited |
マウスカーソルがコンポーネント上から出た。 | MouseEnteredと同じ | |||
mouse.wheel |
MouseWheelMoved |
マウスのホイールを回転された。 | source |
Component |
コンポーネント |
point |
Point |
座標 | |||
modifiers |
Key.Modifiers |
同時に押されていたキーの種類 | |||
rotation |
Int |
||||
keys |
KeyTyped |
キー(文字)が入力された。 | source |
Component |
コンポーネント |
char |
Char |
文字 | |||
modifiers |
Key.Modifiers |
同時に押されていたキーの種類 | |||
location |
Key.Location |
||||
KeyPressed |
キーが押された。 | KeyTypedと同じ | |||
KeyReleased |
キーが離された。 | KeyTypedと同じ |
例えばlistenTo(mouse.moves)
を実行すると、MouseEnteredとMouseExitedが送られてくるようになる。
listenToは可変長引数なので、listenTo(mouse.clicks, mouse.moves)
の様に複数指定することが出来る。
複数のコンポーネントで同じイベント処理を行う場合、トレイトにしてミックスインするのが便利。
trait MyReaction { self: Component => listenTo(this.mouse.clicks) reactions += { case MouseClicked(source, point, modifiers, clicks, triggersPopup) => println(source, modifiers, clicks) } }
contents = new FlowPanel { contents += new Label("ラベル1") with MyReaction contents += new Label("ラベル2") with MyReaction contents += new Label("ラベル3") with MyReaction }
イベントは自分のコンポーネント以外でも受け取れる。
import scala.swing._ import scala.swing.event._
object EventFrameSample extends SimpleSwingApplication { override def top = new MainFrame { title = "サンプル" val label1 = new Label("ラベル1") contents = new FlowPanel { contents += label1 contents += new Label("ラベル2") { listenTo(label1.mouse.clicks) reactions += { case MouseClicked(source, point, modifiers, clicks, triggersPopup) => println("label2", source, modifiers, clicks) } } } listenTo(label1.mouse.clicks) reactions += { case MouseClicked(source, point, modifiers, clicks, triggersPopup) => println("frame", source, modifiers, clicks) } } }
フレーム(MainFrame)のコンストラクター内でlistenToとreactionsの指定を行えば、フレームでイベントを受け取ることが出来る。
ラベル2の中でラベル1をlistenToしてやれば、ラベル2でも(同じイベントを)受け取れる。