#0.はじめに
いま、筆者は絶賛GUIツールを使ったソフトウェアを作る必要に迫られています。
ずっと放置していて最近着手したのですが、思いの外環境構築に手間取ったので備忘録を兼ねてここに書いておきます。
#1.JavaFXって何ぞ?
「JavaでGUIと言ったらAWT!Swing!」と思っている方はいませんか?
実は最近、JavaFXというフレームワークが出てきてかなりGUIツール開発のハードルが下がったと聞いています(聞いているだけ)。
筆者はたまたま、「あー、GUIかー、どうやって作るんだろうなー」とネットを彷徨っていたら見つけました。
今日はそんな便利そうなJavaFXの入り口を少しだけご紹介します。
#2.筆者の環境
- MacBook Pro (Early 2015)
- macOS Mojave (10.14.6)
- IntelliJ IDEA Community Edition (2018.3.1)
- OpenJDK (13.0.1)
#3.環境構築
##3.1.OpenJDKのインストール
###3.1.1.ダウンロード
OpenJDKのサイトから自分が使いたいバージョンのJDKをダウンロードします。
ただし、JavaFX側がJDK11以上を必要とするので注意。
■上記のサイト
この画像の真ん中あたり、macOS/x64
の右にあるtar.gz
のリンクからダウンロードします。
私は13.0.1を使いました。
###3.1.2.インストール
ダウンロードしたtar.gzファイルを展開し、以下のディレクトリに移動します。
/Library/Java/JavaVirtualMachines
/
└── Library
└── Java
└── JavaVirtualMachines
└── jdk-13.0.1.jdk
└── Contents
└── ...
確認として以下のコマンドを実行します。
$ /usr/libexec/java_home -V
Matching Java Virtual Machines (2):
13.0.1, x86_64: "OpenJDK 13.0.1" /Library/Java/JavaVirtualMachines/jdk-13.0.1.jdk/Contents/Home
11.0.2, x86_64: "OpenJDK 11.0.2" /Library/Java/JavaVirtualMachines/jdk-11.0.2.jdk/Contents/Home
/Library/Java/JavaVirtualMachines/jdk-13.0.1.jdk/Contents/Home
実行結果が全く同じでなくても構いません。
今インストールしたバージョンが認識されているか確認してください。
##3.2.プロジェクトのセットアップ
###3.2.1.プロジェクトの作成
IntelliJ IDEAを立ち上げ、Create New Projectから新しいプロジェクトを作ります。
今回はGradleを使ってJavaFXを利用するので、もちろんGradleのプロジェクトを作りましょう。
■プロジェクト作成画面
Project SDKは13になるように設定をしておいてください。
次の画面でGroupId, ArtifactIdを指定します。
さらに次の画面はプロジェクトの設定をする場所ですが、私はここは基本的にいじりません。
Gradle JVMが13になっていることを確認するだけでいいと思います。
その次の画面で使用するフォルダを指定したらプロジェクトが作成されます。
諸々の処理が終わるまで少し待ちましょう。
###3.2.2.build.gradleの設定
※以下、私のプロジェクトでのフォルダ構成で書きます。
フォルダ構成によって記述が変わる箇所は下の方にまとめて書きます。
build.gradleに以下の部分を追記します。
書いていないところは何も編集していません。
plugins {
id 'application'
id 'org.openjfx.javafxplugin' version '0.0.8'
}
dependencies {
//このruntimeOnly群はクロスプラットフォーム対応のjarを作るためのものです。
//不必要なものは消すとjarファイルのサイズを小さくできます。
runtimeOnly "org.openjfx:javafx-base:$javafx.version:win"
runtimeOnly "org.openjfx:javafx-base:$javafx.version:linux"
runtimeOnly "org.openjfx:javafx-base:$javafx.version:mac"
runtimeOnly "org.openjfx:javafx-controls:$javafx.version:win"
runtimeOnly "org.openjfx:javafx-controls:$javafx.version:linux"
runtimeOnly "org.openjfx:javafx-controls:$javafx.version:mac"
runtimeOnly "org.openjfx:javafx-fxml:$javafx.version:win"
runtimeOnly "org.openjfx:javafx-fxml:$javafx.version:linux"
runtimeOnly "org.openjfx:javafx-fxml:$javafx.version:mac"
runtimeOnly "org.openjfx:javafx-graphics:$javafx.version:win"
runtimeOnly "org.openjfx:javafx-graphics:$javafx.version:linux"
runtimeOnly "org.openjfx:javafx-graphics:$javafx.version:mac"
}
javafx {
version = "13"
modules = [ 'javafx.controls', 'javafx.fxml' ]
}
mainClassName = 'maru.test.Launcher'
jar {
manifest {
attributes 'Main-Class': 'maru.test.Launcher'
}
from {
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
}
}
#4.サンプルのプロジェクトを動かす
##4.1.サンプルコードの実装
サンプルコードはOpenJFXの公式さんからお借りしました。
package maru.test;
import javafx.application.Application;
public class Launcher {
public static void main(String... args){
Application.launch(MainApp.class);
}
}
package maru.test;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class MainApp extends Application {
@Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("scene.fxml"));
Scene scene = new Scene(root);
scene.getStylesheets().add(getClass().getResource("styles.css").toExternalForm());
stage.setTitle("JavaFX and Gradle");
stage.setScene(scene);
stage.show();
}
}
package maru.test;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import java.net.URL;
import java.util.ResourceBundle;
public class FXMLController implements Initializable {
@FXML
private Label label;
@Override
public void initialize(URL url, ResourceBundle rb) {
String javaVersion = System.getProperty("java.version");
String javafxVersion = System.getProperty("javafx.version");
label.setText("Hello, JavaFX " + javafxVersion + "\nRunning on Java " + javaVersion + ".");
}
}
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.StackPane?>
<StackPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="maru.test.FXMLController">
<children>
<Label fx:id="label" text="Label" />
</children>
</StackPane>
.label {
-fx-text-fill: blue;
}
##4.2.コンパイル、実行
右上の方にあるGradleをクリック、Tasks>build>buildを実行します。
それが終わったら少し上のTasks>application>runを実行します。
■「こんな感じの」
build/libs/
にjarファイルができていると思います。
このjarファイルはfatjar(ライブラリとかも含んでいるjarファイル)なので、誰のPCでも動くはずです。
ごめんなさい多分嘘つきました。fatjarが欲しかったらshadowを入れましょう。
##4.3.フォルダ構成によって記述が変わる場所
<>
で囲まれている場所をよしなに変えてください。
フォルダ構成に左右される箇所だけ抜き出しています。
ファイル名 | |
---|---|
build.gradle | 2箇所 |
Launcher.java | 1箇所 |
MainApp.java | 2箇所 |
scene.fxml | 1箇所 |
mainClassName = '<Applicationクラスを継承していないランチャー用のクラス>'
jar {
manifest {
attributes 'Main-Class': '<上のmainClassNameと同じ>'
}
}
public static void main(String... args){
Application.launch(<Applicationクラスを継承しているクラス>.class);
}
@Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("<fxmlファイル>"));
scene.getStylesheets().add(getClass().getResource("<cssファイル>").toExternalForm());
}
<StackPane (中略) fx:controller="<Controllerクラス>">
おそらく以上です。見落としがあったらごめんなさい。。。
#5.最後に
どうでしたか?思ったより簡単だったのではないでしょうか?
ちなみに、画面の構築にはSceneBuilderが便利です。
IntelliJ IDEAの設定をすればこんなこともできちゃいます。
■こんなこと
これでGUIアプリケーション開発のハードルがグッと下がったのではないでしょうか。
皆さんもよいGUIアプリケーションライフをお楽しみください!
#6.参考文献