JavaFXをKotlinらしく使いましょうなライブラリ、フレームワーク。
ガイドの最初の方だけ見た。
楽に書けるなぁと思いつつ。
準備
Gradleを使っているので、dependencies
を追加すればすぐ使えるようになる。
IntelliJが自動生成してくれるbuild.gradle
にTornadoFXを追加すると以下のような感じになる
buildscript {
ext.kotlin_version = '1.2.30'
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
group 'com.github.dekirukigasuru'
version '1.0-SNAPSHOT'
apply plugin: 'kotlin'
repositories {
mavenCentral()
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
compile 'no.tornado:tornadofx:1.7.15'
}
compileKotlin {
kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
kotlinOptions.jvmTarget = "1.8"
}
基本コード
App
を継承したクラスを一つ、そのクラスにつけるView
を継承したクラス一つがそれぞれ必要。
View
においてroot
をオーバーライドして画面を構成していく。
その構成をJavaFXノードでしていくのだが、Kotlinぽく記述できる用意が色々されている感じ。
import javafx.application.Application
import tornadofx.*
class MyApp: App(MyView::class)
class MyView: View() {
override val root = vbox {}
}
fun main(args: Array<String>) {
Application.launch(MyApp::class.java, *args)
}
これでウインドウが表示される。
main()
関数はなくても動くみたい。JavaFXがそもそもそうらしい。
Viewを切り替える
画面は切り替えられる。エフェクト付きで。
onDock()``onUndock()
を実装しておくと切り替え前後で呼び出される。
import javafx.application.Application
import tornadofx.*
class MyApp: App(MyView::class)
class MyView: View() {
override val root = vbox {
button("Go to MyView2") {
action {
replaceWith(MyView2::class)
}
}
}
override fun onDock() {
super.onDock()
println("docking view1")
}
override fun onUndock() {
super.onUndock()
println("undocking view1")
}
}
class MyView2: View() {
override val root = vbox {
button("Go to MyView1") {
action {
replaceWith(MyView::class, ViewTransition.Slide(0.3.seconds, ViewTransition.Direction.LEFT))
}
}
}
override fun onDock() {
super.onDock()
println("docking view2")
}
override fun onUndock() {
super.onUndock()
println("undocking view2")
}
}
fun main(args: Array<String>) {
Application.launch(MyApp::class.java, *args)
}
MVCと非同期的な
表示とデータ処理は分けて実装できるようになっている。
例によって、時間のかかる処理をそのまま記述すると画面が固まる。
また、画面の更新はUIスレッドからしか行えない。
その辺簡単に書けるようになっている。
import javafx.application.Application
import tornadofx.*
class MyApp: App(MyView::class)
class MyView: View() {
val controller: MyController by inject()
override val root = vbox {
label("Input")
val inputField = textfield()
button("Commit") {
action {
runAsync {
controller.writeToDb(inputField.text)
} ui {
inputField.clear()
}
}
}
}
}
class MyController: Controller() {
fun writeToDb(inputValue: String) {
println("Writing $inputValue to database")
}
}
fun main(args: Array<String>) {
Application.launch(MyApp::class.java, *args)
}
ただし、難しいことする場合はRxを推奨している。
TornadoFX用のRxがある
その他
プロジェクトを簡単に作成できるIntelliJ用プラグインがある。