Kotlin+JavaFXの基本的なコード

  • 9
    Like
  • 0
    Comment
More than 1 year has passed since last update.

KotlinでJavaFXを書く場合、どのように書けば良いかというテンプレです(主に自分用)。

コード

共通

Main.kt
import javafx.application.Application

/**
 * メインメソッド
 */
fun main(args: Array<String>) {
    // MyApplicationクラスを開始させる
    //(MyApplicationクラスはJavaのClassクラスとして渡す)
    Application.launch(MyApplication::class.java, *args)
}
MyApplication.kt
import javafx.application.Application
import javafx.fxml.FXMLLoader
import javafx.scene.Parent
import javafx.scene.Scene
import javafx.stage.Stage

/**
 * GUI全体に関するクラス
 */
class MyApplication : Application() {
    /**
     * GUIをスタートさせる
     * @param primaryStage 土台となるコンテナ(トップレベルコンテナ)
     */
    override fun start(primaryStage: Stage) {
        //GUIのタイトルを設定
        primaryStage.title = "Hello World"

        //Scene(見えないコンテナ)にsample.fxmlの内容を当てはめる
        primaryStage.scene = Scene(FXMLLoader.load<Parent>(this.javaClass.getResource("sample.fxml")), 300.0, 275.0)

        //GUIを表示
        primaryStage.show()
    }
}
sample.css
/*スタイル名は先頭に-fxがつく*/
Label#label1 {
    -fx-font-family: Serif;
    -fx-font-size: 24pt;
}

パターン1

sample.fxml
<!--importはJavaやKotlinと同様に書く-->
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.BorderPane?>
<?import java.net.URL?>

<!--パネル-->
<!--fx:controllerでコントローラを指定-->
<BorderPane xmlns="http://javafx.com/javafx"
            xmlns:fx="http://javafx.com/fxml"
            fx:controller="Controller">
    <!--スタイルシート-->
    <stylesheets>
        <URL value="@sample.css"/>
    </stylesheets>

    <!--部品-->
    <!--fx:idでコントローラやスタイルファイルで使うIDを指定-->
    <top>
        <Label fx:id="label1" text="This is FXML!"/>
    </top>
    <center>
        <TextField fx:id="field1"/>
    </center>
    <bottom>
        <Button fx:id="btn1" onAction="#btn1OnAction" text="Click"/>
    </bottom>
</BorderPane>
Controller.kt
import javafx.fxml.FXML
import javafx.scene.control.Button
import javafx.scene.control.Label
import javafx.scene.control.TextField

/**
 * sample.fxmlで定義された部品に関するクラス(コントローラ)
 */
class Controller {
    //フィールドやメソッドの先頭に@FXMLアノテーションを付けることで、sample.fxmlとリンクする

    //lateinit(遅延初期化オプション)を付けることで、nullチェックを避ける
    @FXML lateinit var label1: Label
    @FXML lateinit var field1: TextField
    @FXML lateinit var btn1: Button

    @FXML
    fun btn1OnAction() {
        this.label1.text = "あなたは、「${this.field1.text}」と書いた。"
    }
}

パターン2

sample.fxml
<!--importはJavaと同様に書く-->
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.BorderPane?>
<?import java.net.URL?>

<!--パネル-->
<!--fx:controllerでコントローラを指定-->
<BorderPane xmlns="http://javafx.com/javafx"
            xmlns:fx="http://javafx.com/fxml"
            fx:controller="Controller">
    <!--スタイルシート-->
    <stylesheets>
        <URL value="@sample.css"/>
    </stylesheets>

    <!--部品-->
    <!--fx:idでコントローラやスタイルファイルで使うIDを指定-->
    <top>
        <Label fx:id="label1" text="This is FXML!"/>
    </top>
    <center>
        <TextField fx:id="field1"/>
    </center>
    <bottom>
        <Button fx:id="btn1" text="Click"/>
    </bottom>
</BorderPane>
Controller.kt
import javafx.event.EventHandler
import javafx.fxml.FXML
import javafx.fxml.Initializable
import javafx.scene.control.Button
import javafx.scene.control.Label
import javafx.scene.control.TextField
import java.net.URL
import java.util.*

/**
 * sample.fxmlで定義された部品に関するクラス(コントローラ)
 */
class Controller : Initializable {
    //フィールドやメソッドの先頭に@FXMLアノテーションを付けることで、sample.fxmlとリンクする

    //lateinit(遅延初期化オプション)を付けることで、nullチェックを避ける
    @FXML lateinit var label1: Label
    @FXML lateinit var field1: TextField
    @FXML lateinit var btn1: Button

    override fun initialize(location: URL?, resources: ResourceBundle?) {
        this.btn1.onAction = EventHandler {
            this.label1.text = "あなたは、「${this.field1.text}」と書いた。"
        }
    }
}

参考文献