1. 序章

このチュートリアルでは、 TornadoFX とは何か、およびOracleJDKとOpenJDKでどのように設定できるかを見ていきます。 また、アーキテクチャについて説明し、アーキテクチャのさまざまな部分を見ていきます。 最後に、いくつかのウィジェットの使用方法の概要を説明します。

始める前に、 JavaFX にある程度精通していることは良いことですが、必須ではありません。 TornadoFXはKotlin用のJavaFXフレームワークであるため。 ビューの定義、依存性注入、委任されたプロパティ、コントロール拡張機能、その他の実用的な機能など、さまざまな目的でKotlinのパワーを解き放つように設計されています。

また、TornadoFXはまだJava9および10と互換性がないため、Java11を使用することに注意してください。

2. 設定

このセクションでは、MavenとGradleを使用してTornadoFXプロジェクトを最初からセットアップする方法を示します。

2.1. OpenJDK

LinuxでOpenJDKを使用する可能性が高いので、それから始めます。 これから説明するように、OpenJDKを使用してTornadoFXを設定するのは難しいです。

まず、OpenJDKをバージョン11にアップグレードする必要があります。 次に、Gradleの場合、 build.gradle 次のようになります。

plugins {
    id 'org.jetbrains.kotlin.jvm' version '1.5.10'
    id 'org.openjfx.javafxplugin' version '0.0.8'
    id 'application'
}

compileKotlin {
    kotlinOptions.jvmTarget = "11"
}

compileTestKotlin {
    kotlinOptions.jvmTarget = "11"
}
javafx {
    version = "11.0.2"
    modules = ['javafx.controls', 'javafx.graphics']
}
repositories {
    mavenCentral()
}

dependencies {
    // Align versions of all Kotlin components
    implementation platform('org.jetbrains.kotlin:kotlin-bom')

    implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'

    // Use the tornadofx
    implementation "no.tornado:tornadofx:1.7.20"
}

TornadoFXライブラリの最新バージョンを確認するには、 TornadoFXMavenページにアクセスしてください。OpenJFXプラグインのバージョンについては、OpenJFXプラグインMavenページを確認してください。 Mavenの場合、pom.xmlで使用するTornadoFXのバージョンを宣言する必要があります。

<properties>
    <tornadofx.version>1.7.20</tornadofx.version>
</properties>

次に、トルネードライブラリを依存関係として追加する必要があります。

<dependency>
    <groupId>no.tornado</groupId>
    <artifactId>tornadofx</artifactId>
    <version>1.7.20</version>
</dependency>

次に、 JavaFXUIツールキットのベースAPIを定義する必要があります。

<dependency>
    <groupId>org.openjfx</groupId>
    <artifactId>javafx-base</artifactId>
    <version>17-ea+11</version>
</dependency>

ListView Menubar などのJavaFXコントロールを使用するには、javafx-controls依存関係を定義する必要があります。

<dependency>
    <groupId>org.openjfx</groupId>
    <artifactId>javafx-controls</artifactId>
    <version>17-ea+11</version>
</dependency>

最後に、JavaFXのmavenプラグインを他のプラグインと一緒に追加する必要があります。

<plugins>
    <plugin>
        <!--Maven plugin to run JavaFX 11+ applications-->
        <groupId>org.openjfx</groupId>
        <artifactId>javafx-maven-plugin</artifactId>
        <version>0.0.3</version>
        <configuration>
            <mainClass>MyApp</mainClass>
        </configuration>
    </plugin>
    <!--other libraries like kotlin-maven or maven-compiler-->
</plugins>

さらに、module-info.jarsrc/ main /kotlinフォルダーに追加する必要があります。

module TFXSAMPLE {
    requires javafx.controls;
    requires javafx.graphics;
    requires javafx.base;
    requires tornadofx;
    requires kotlin.stdlib;
    exports com.example.demo.app to javafx.graphics, tornadofx;
    exports com.example.demo.view to tornadofx;
}

2.2. Oracle JDK

Oracle JDKを使用している場合、JFXモジュールライブラリがすでに含まれているため、セットアップの処理が異なり、はるかに簡単です。

Gradleでは、TornadoFXライブラリを提供する必要があります。

repositories {
    mavenCentral()
}

dependencies {
    implementation 'no.tornado:tornadofx:1.7.20'
}

Mavenの場合も同じですが、追加する必要があるのはTornadoFXライブラリだけです。

<dependency>
    <groupId>no.tornado</groupId>
    <artifactId>tornadofx</artifactId>
    <version>1.7.20</version>
</dependency>

3. アプリケーションの基本

他のJavaアプリと同様に、TornadoFXアプリには開始点としてメインクラスが必要です。 したがって、最初にアプリケーションを定義する必要があります。 app、という名前のパッケージを作成してから、MyAppという名前のKotlinクラスを追加しましょう。 次に、初期ビュークラスでアプリを初期化します。 ビュークラスを作成する方法については後で説明します。

今のところ、HelloWorldという名前のビュークラスがあるとしましょう。

class MyApp: App(HelloWorld::class)

4. クラスを見る

ビューには、ユーザーに表示する必要のある情報の表現が含まれています。 ビューには、JavaFX Stage と同様に、表示ロジックとノードのレイアウトが含まれています。 ただし、JavaFXとは異なり、ビューの定義に別の言語を使用することはありません。 TornadoFXは、ネイティブKotlinを使用して、型安全性とコンパイル済みCSSをゲームに組み込むオプションを提供します。

次に、 HelloWorld ビュークラスを作成し、v iew という名前のパッケージを作成して、 HelloWorld:という名前のKotlinクラスを追加しましょう。

import tornadofx.*
class HelloWorld : View() {
    override val root = hbox {
        label("Hello world")
    }
}

また、 label をインスタンス化し、それを hbox (Horizontal Box)に割り当てると、すべてがrootの親になります。

また、tornadofx。*のインポートにも注意してください。 これは、すべてのTornadoFX関連ファイルに存在する必要があります。 フレームワークの機能の一部は、インポートなしではIDEで検出できないため、これは重要です。 このインポートにより、私たちが本当になくてはならないいくつかの高度な拡張機能が有効になりました。

上記の例を見ると、 HelloWorldクラスがViewから派生していることがわかります。ここで、アプリを実行すると、次のようになります。

5. スタイリング

TornadoFXは、型安全性とコンパイルされたCSSをJavaFXにもたらすオプションを提供します。 独自のクラスでスタイルを作成するか、コントロール宣言内でインラインで作成するかを簡単に選択できます。 上記の例では、ラベルのスタイルを定義できます。

class Styles : Stylesheet() {
    init {
        label {
            padding = box(10.px)
            fontSize = 20.px
            fontWeight = FontWeight.BOLD
        }
    }
}

次に、アプリケーションの初期化に使用したコンストラクターを変更し、Stylesクラスを2番目の引数として渡す必要があります。

class MyApp: App(MainView::class, Styles::class)

ここでも、 app、を実行すると、ラベルのスタイルが表示されます。

インラインスタイルでも同じことができました。 このスタイルは、ノードに適用されている他のスタイルを上書きします。 これは、一般的なスタイル宣言に干渉したくない場合に特に便利です。

label("Hello world") {
    style {
        padding = box(10.px)
        fontSize = 20.px
        fontWeight = FontWeight.BOLD
    }
}

6. インジェクションを表示

TornadoFXは、依存性注入を大幅にサポートします。 このフレームワークにはさまざまなレイヤーを簡単に挿入でき、ネイティブにサポートされています。 次に、ビューを挿入する方法を見ていきます。

ビューインジェクションは、 find()または inject()メソッドのいずれかを介して実行できます。 findinjectの違いは、 inject()メソッドを使用すると、デリゲートが特定のコンポーネントに遅延割り当てされることです。

怠惰に割り当てられるということは、コンポーネントを初めて呼び出すことを意味します。 注入されたリソースで関数を初めて呼び出すときに、実際のインスタンスが作成されます。 ただし、 find()メソッドの場合、デリゲートではなくビューのシングルトンインスタンスを取得します。

ただし、injectを使用することをお勧めします。これは、コンポーネントに循環依存関係を持たせることができ、遅延読み込みの利点があるためです。

class SampleView: View() {
    // Explicitly retrieve HeaderView
    private val headerView = find(HeaderView::class)
    
    // Create a lazy delegate
    private val footerView: FooterView by inject()

    override val root = borderpane {
        top = headerView.root
        bottom = footerView.root
    }
}

7. コントローラー

テスト容易性や保守性など、ロジックをビューから分離することをお勧めする理由はたくさんあります。

TornadoFXでは、3層アーキテクチャとそのバリアントを完全にサポートしています。 これを実現する方法は、ビューを挿入する方法と似ています。 まず、コントローラーを定義します。 次に、 Controller スーパークラスから派生させ、ビューに挿入します。

class SampleView : View() {
    private val controller: SampleController by inject()
    private val input = SimpleStringProperty()

    override val root = form {
        fieldset {
            field() {
                textfield(input)
            }

            button("Post") {
                action {
                    controller.postApi(input.value)
                    input.value = ""
                }
            }
        }
    }
}

class SampleController: Controller() {
    fun postApi(inputValue: String) {
        println("Doing backend stuff with $inputValue")
    }
}

8. 結論

明らかに、この分野には他にも多くのトピックについて話すことができますが、このチュートリアルの主な目的は、TornadoFXを紹介し、開始するのに十分な情報を提供することでした。

詳細については、公式のドキュメントをご覧ください。  チュートリアルの完全なソースコードは、GitHubから入手できます。