3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Scala から FXML を読み込んでフォームアプリケーションを作る

Posted at

以前「Scala fxml」と検索したら、手動でイベントハンドラを登録したりしていてややこしかったので、シンプルに Scala から .fxml を読み込んでハンドラを登録するだけの記事を書きました。

流れ

やることは以下の 3 つです。

  1. .fxml ファイルを用意する
  2. コントローラーを書く
  3. .fxml ファイルを読み込んでコントローラーを登録する

import 文などは適宜追加してください。
一応 GitHub のリポジトリに雛型をおいてあります。

.fxml ファイルの用意

FXML は、JavaFX で使われる GUI のマークアップ言語です。
GLUON Scene Builder などを使えばとても簡単に GUI を作成することができます。

今回はとりあえずこんな感じのフォームにします。

preview.png

BorderPane の上に Button と Label が置いてあるだけです。
アプリケーションを作ることそのものが目的ではないので……。
中身はこんな感じです。

main.fxml
<?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 などのプロパティは、イベントハンドラを登録するさいにメソッド名として使用されます。

コントローラーの設定

MainController.scala
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 を読み込んでコントローラーを設定する

Main.scala
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 になっていることに気づかず、永遠に型が解決されなくて苦しんだので注意してください。

これでフォームの見た目の作成と、イベントハンドラの登録ができました。
実際に動かすと、以下のようになります。きちんと実行できていますね。

form.gif

おわりに

というわけで Scala アドベントカレンダー 2 日目でした。地味な記事ですみません。
まだまだ始まったばかりですが、個人的には Spark とか機械学習の記事が楽しみです!

3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?