IntelliJ+Gradle+JavaFXでGUIアプリケーション開発

ソフトウェア開発

前回の記事でJavaFXで開発したGUIアプリケーションについて少し触れましたが、今回はもう少し具体的な機能やインタフェースについて説明したいと思います。

実はこのアプリケーション、家族から「こんな感じのアプリがあったら便利だなあ」という声があったので、Javaの勉強がてら開発したものになります。本やスクールでプログラミングを勉強するのももちろんよいですが、実際自分で手を動かして開発するのが一番身に付きます。今回の内容を少しでも役立てて、読者の方がJavaアプリケーションを作成されることを願っております。

開発コード

GitHub - shsax12/ImageShuffle
Contribute to shsax12/ImageShuffle development by creating an account on GitHub.

開発環境

バージョン
JDK11.0.9
Gradle4.10.3
JavaFX11.0.2

Gradle

ゴールはコンソール上で実行するというよりは、実行可能なjarファイル形式で納品したかったので、IntelliJでGradleプロジェクトを作成しました。build.gradleはこちらになります。

plugins {
    id 'java'
    id 'application'
    id 'org.openjfx.javafxplugin' version '0.0.8'
    id 'com.github.johnrengelman.shadow' version '4.0.4'
}

group 'imageshuffle'
version '1.0-SNAPSHOT'

sourceCompatibility = 1.8

repositories {
    mavenCentral()
}

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.12'
    runtimeOnly "org.openjfx:javafx-base:$javafx.version:win"
    runtimeOnly "org.openjfx:javafx-base:$javafx.version:mac"
    runtimeOnly "org.openjfx:javafx-controls:$javafx.version:win"
    runtimeOnly "org.openjfx:javafx-controls:$javafx.version:mac"
    runtimeOnly "org.openjfx:javafx-fxml:$javafx.version:win"
    runtimeOnly "org.openjfx:javafx-fxml:$javafx.version:mac"
    runtimeOnly "org.openjfx:javafx-graphics:$javafx.version:win"
    runtimeOnly "org.openjfx:javafx-graphics:$javafx.version:mac"
}

javafx {
    version = "11.0.2"
    modules = [ 'javafx.controls', 'javafx.fxml' ]
}

mainClassName = 'imageshuffle.Launcher'

jar {
    manifest {
        attributes 'Main-Class': 'imageshuffle.Launcher'
    }
    from {
        configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
    }
}

JavaFX

Java11からはJavaFXが含まれていないので別途インストールする必要がありますが、Gradleで使用できるプラグイン(org.openjfx.javafxplugin)が存在するので簡単のためそちらを使っています。

アプリケーション本体

アプリケーションの機能などの詳細はREADMEを参照いただければと思いますが、簡単に説明すると、画像とそれに対応するテキスト(説明文)を暗記するために使用するGUIアプリケーションになっています。データ登録画面で画像とテキストの対応付けを作成し、テスト画面でそれらを表示していくようなフローになっています。

Launcherクラスにmainメソッドを置いて、そこからstartメソッドを持つMainAppクラスを呼び出しています。MainAppクラスにはfxmlのloadや全画面で共通して使用するデータを持たせています。Controllerクラスはボタンをクリックしたときの動作やラベルへの表示など、画面ごとの動作を実装しています。最終的なプロジェクト構成はこのようになっています。

アプリケーション配布(Jar)

簡単に使用できるように、ダブルクリックで実行可能なJar形式で出力するようにしました。その際、buildしてデフォルトで作成されるjarファイルには依存ライブラリが含まれていないため、Shadowプラグイン(com.github.johnrengelman.shadow)を使ってfat jarファイルを作成しました。これをbuild.gradleに追記してbuilldすると、*-all.jarというファイルが作成されるので、ダブルクリックで簡単にアプリケーションが実行できるようになります。

ハマったポイント

タプルを使いたい

File型の画像ファイルとString型のテキストをタプルで扱いたかったのですが、Javaにはタプルが存在しないことを知りました。独自に実装することも可能そうでしたが、フィールドだけを持つシンプルな独自クラス(Datasetクラス)を作ることにしました。

resourcesパス

画面ごとに作成したfxmlファイルをsrc/main/resourcesの直下に配置したときのパス指定が少しわかりづらかったです。getResourceで呼び出すときには以下のように/が必要になります。

getResource("/top.fxml")

実行ファイルのJava互換性

これが一番ハマってしまったのですが、上記の方法で最初jarを作ったとき、コマンドラインからは実行できるのにダブルクリックで開こうとするとエラーになってしまっていました。開発自体はJava11を使っていたのですが、恐らくダブルクリックで開くときはJava8が使用されるようで、build.gradleにこの1行を追記することで問題なくダブルクリックでも実行できるようになりました。

sourceCompatibility = 1.8

GradleとShadowのバージョン

GradleとShadowプラグインのメジャーバージョンが揃っていれば基本的に問題ありませんが、これがずれていると互換性の問題でbuildが通らない可能性があります。Gradle Shadow Pluginのバージョン情報に記載があるので、問題がある場合にはこちらを参照してバージョンを修正してみてください。

まとめ

JavaFXで作ったアプリケーションの第1版について、構成や機能の説明をしました。家族にはこれを使ってもらいながら、改善要件があれば随時改修していこうと思っています。プロジェクトの構成やコードの設計などもし改善ポイントがあればコメントいただけると大変嬉しいです。

最後までお読みいただきありがとうございました。

タイトルとURLをコピーしました