Kotlin + Tornadofx(JavaFX)でGUIアプリケーション開発

Kotlin + JavaFXでGUIを表示するまでのメモ書きです。
地味に起動まで時間がかかったのでエラーを含めて記載しておきます。

環境は
Ubuntu 18.04
OpenJDK 11
です。

Tornadofx



Kotlin + JavaFXなGUIアプリケーションを作成する場合は、Tornadofxを使用すると簡単なようです。
https://tornadofx.io/

こちらのドキュメントを参考に進めていきます。
https://edvin.gitbooks.io/tornadofx-guide/


雛形アプリの作成



gradleでKotlinプロジェクトの雛形を生成・ビルド
こちらの手順と同様、


$ gradle help --task :init



で雛形を作成します。

App.ktをMyApp.ktにリネーム。
※TornadofxではAppというクラスを継承するようなので、余計な問題発生を避けて。

サンプルを参考に以下の内容を記載します。

・MyApp.kt


  1. package sample
  2. import tornadofx.*
  3. class MyApp: App(MyView::class)
  4. fun main(args: Array<String>) {
  5. launch<MyApp>(args)
  6. }




MyView.ktを新規作成。
こちらもサンプルを参考に以下の内容を記載します。

・MyView.kt


  1. package sample
  2. import tornadofx.*
  3. class MyView: View() {
  4.     override val root = vbox {
  5.         button("Press me")
  6.         label("Waiting")
  7.     }
  8. }




build.gradleを編集。
tornadofxの指定追加と、mainClassNameを「sample.MyAppKt」に変更します。

・build.gradle


  1. plugins {
  2.     id 'org.jetbrains.kotlin.jvm' version '1.3.61'
  3.     id 'application'
  4. }
  5. repositories {
  6.     jcenter()
  7. }
  8. dependencies {
  9.     // この行を追加
  10.     compile 'no.tornado:tornadofx:1.7.20'
  11.     implementation platform('org.jetbrains.kotlin:kotlin-bom')
  12.     implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'
  13.     testImplementation 'org.jetbrains.kotlin:kotlin-test'
  14.     testImplementation 'org.jetbrains.kotlin:kotlin-test-junit'    
  15. }
  16. application {
  17.     // AppKtからMyAppKtに変更
  18.     mainClassName = 'sample.MyAppKt'    
  19. }




ビルドを実行するとエラーになります。


$ gradle run

> Task :run FAILED
Exception in thread "main" java.lang.NoClassDefFoundError: javafx/application/Application
        at java.base/java.lang.ClassLoader.defineClass1(Native Method)
        at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1016)
        at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:174)
        at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:800)
        at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:698)
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:621)
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:579)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
        at java.base/java.lang.ClassLoader.defineClass1(Native Method)
        at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1016)
        at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:174)
        at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:800)
        at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:698)
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:621)
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:579)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
        at sample.MyAppKt.main(MyApp.kt:13)
Caused by: java.lang.ClassNotFoundException: javafx.application.Application
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
        ... 19 more

FAILURE: Build failed with an exception.



1つずつエラーを潰していきます。




JavaFX



知らなかったのですが、OpenJDKってJavaFXが同梱されていないんですね。
Ubuntu 18.04 + OpenJDK 11の環境にJavaFXをaptでインストール

「openjfx」をaptでインストール。


$ sudo apt install openjfx



これで「/usr/share/openjfx/lib/」に資産が配置されます。

build.gradleを編集。
インストールしたJavaFXのパスをクラスパスに含めます。

・build.gradle


  1. plugins {
  2.     id 'org.jetbrains.kotlin.jvm' version '1.3.61'
  3.     id 'application'
  4. }
  5. repositories {
  6.     jcenter()
  7. }
  8. dependencies {
  9.     compile 'no.tornado:tornadofx:1.7.20'
  10.     // JavaFXのクラスパス追加
  11.     compile fileTree(dir: '/usr/share/openjfx/lib/', include: '*.jar')
  12.     implementation platform('org.jetbrains.kotlin:kotlin-bom')
  13.     implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'
  14.     testImplementation 'org.jetbrains.kotlin:kotlin-test'
  15.     testImplementation 'org.jetbrains.kotlin:kotlin-test-junit'    
  16. }
  17. application {
  18.     mainClassName = 'sample.MyAppKt'    
  19. }




ビルドを実行するとエラーになります。


$ gradle run

> Task :compileKotlin FAILED
e: /home/baranche/dev/kotlin/sample/src/main/kotlin/sample/MyApp.kt: (11, 3):
Cannot inline bytecode built with JVM target 1.8 into bytecode that is being built with JVM target 1.6.
Please specify proper '-jvm-target' option

FAILURE: Build failed with an exception.





jvmTarget



jvmTargetの指定を変えれば良さそうなのはエラーメッセージから読み取れるのですが、
Android開発のドキュメントしか見つからず途方にくれているとリファレンスに答えがありました。
https://kotlinlang.org/docs/reference/using-gradle.html

tasks.withTypeでkotlinOptionsを指定してやります。

・build.gradle


  1. plugins {
  2.     id 'org.jetbrains.kotlin.jvm' version '1.3.61'
  3.     id 'application'
  4. }
  5. repositories {
  6.     jcenter()
  7. }
  8. dependencies {
  9.     compile 'no.tornado:tornadofx:1.7.20'
  10.     compile fileTree(dir: '/usr/share/openjfx/lib/', include: '*.jar')
  11.     implementation platform('org.jetbrains.kotlin:kotlin-bom')
  12.     implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'
  13.     testImplementation 'org.jetbrains.kotlin:kotlin-test'
  14.     testImplementation 'org.jetbrains.kotlin:kotlin-test-junit'    
  15. }
  16. application {
  17.     mainClassName = 'sample.MyAppKt'    
  18. }
  19. // JVMのターゲットを変更
  20. tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach {
  21.     kotlinOptions {
  22.         jvmTarget = '1.8'
  23.     }
  24. }




ビルドを実行すると


$ gradle run



やっと動いてくれました。

a22_01.png


【参考URL】

How to install openjfx along with openjdk-11?
Why kotlin gradle plugin cannot build with 1.8 target?
https://kotlinlang.org/docs/reference/using-gradle.html

関連記事

コメント

非公開コメント

プロフィール

Author:symfo
blog形式だと探しにくいので、まとめサイト作成中です。
Symfoware まとめ

PR




検索フォーム

月別アーカイブ