以前「Scala fxml」と検索したら、手動でイベントハンドラを登録したりしていてややこしかったので、シンプルに Scala から .fxml を読み込んでハンドラを登録するだけの記事を書きました。
流れ
やることは以下の 3 つです。
- .fxml ファイルを用意する
- コントローラーを書く
- .fxml ファイルを読み込んでコントローラーを登録する
import 文などは適宜追加してください。
一応 GitHub のリポジトリに雛型をおいてあります。
.fxml ファイルの用意
FXML は、JavaFX で使われる GUI のマークアップ言語です。
GLUON Scene Builder などを使えばとても簡単に GUI を作成することができます。
今回はとりあえずこんな感じのフォームにします。
BorderPane の上に Button と Label が置いてあるだけです。
アプリケーションを作ることそのものが目的ではないので……。
中身はこんな感じです。
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.BorderPane?>
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1">
<left>
<Button fx:id="button1" mnemonicParsing="false" onMouseClicked="#button1_MouseClicked" text="Button" BorderPane.alignment="CENTER" />
</left>
<center>
<Label fx:id="label1" prefHeight="17.0" prefWidth="265.0" text="Label" BorderPane.alignment="CENTER" />
</center>
</BorderPane>
fx:id
というプロパティが、コントロールを入れる変数に使われます。
onMouseClicked
などのプロパティは、イベントハンドラを登録するさいにメソッド名として使用されます。
コントローラーの設定
object MainController {
@FXML
private[this] var button1: Button = _
@FXML
private[this] var label1: Label = _
@FXML
private[this] def button1_MouseClicked(e: MouseEvent): Unit = {
label1.setText("Hello, world!")
}
}
今回はシンプルに、ボタンを押したら Label の表示が "Hello, world!" に切り替わるようにしました。
@FXML
アノテーションを付けることで、.fxml ファイル読み込み時に変数がインジェクションされる仕組みのようです。
変数名やメソッド名が、.fxml ファイルのプロパティに対応していることに注意してください。
FXML を読み込んでコントローラーを設定する
object Main extends App {
Application.launch(classOf[Main], args: _*)
}
class Main extends Application {
override def start(primaryStage: Stage): Unit = {
val loader = new FXMLLoader(getClass.getResource("main.fxml"))
loader.setController(MainController)
val root: Parent = loader.load()
val scene = new Scene(root, 800, 500)
primaryStage.setTitle("GUI test")
primaryStage.setScene(scene)
primaryStage.show()
}
}
重要なのは以下の 2 行です。
val loader = new FXMLLoader(getClass.getResource("main.fxml"))
loader.setController(MainController)
1 行目で main.fxml を読み込み、2 行目でコントローラーを設定しています。
なお、この書き方は JDK8 以降でのみ有効です。以前プロジェクト設定が JDK7 になっていることに気づかず、永遠に型が解決されなくて苦しんだので注意してください。
これでフォームの見た目の作成と、イベントハンドラの登録ができました。
実際に動かすと、以下のようになります。きちんと実行できていますね。
おわりに
というわけで Scala アドベントカレンダー 2 日目でした。地味な記事ですみません。
まだまだ始まったばかりですが、個人的には Spark とか機械学習の記事が楽しみです!