Now, the author is under pressure to create software that uses the acclaimed GUI tools. ~~ I left it for a long time ~~ I started it recently, but it took a lot of time to build an unexpected environment, so I will write it here as a memorandum.
Is there anyone who thinks "GUI in Java is AWT! Swing!"? Actually, I heard that the hurdle for GUI tool development has been lowered considerably recently with the emergence of a framework called JavaFX (I just heard).
I happened to find it when I was wandering around the net, "Ah, GUI? How do I make it?" Today, I would like to introduce a few entrances to JavaFX that are so convenient.
Download the version of JDK you want to use from OpenJDK Site. However, note that JavaFX requires JDK 11 or higher.
■ The above site
In the middle of this image, download it from the tar.gz
link to the right of macOS / x64
.
I used 13.0.1.
Extract the downloaded tar.gz file and change to the following directory.
/Library/Java/JavaVirtualMachines
/
└── Library
└── Java
└── JavaVirtualMachines
└── jdk-13.0.1.jdk
└── Contents
└── ...
Execute the following command as confirmation.
$ /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
The execution results do not have to be exactly the same. Make sure the version you just installed is recognized.
Launch IntelliJ IDEA and create a new project from Create New Project. This time we will use JavaFX with Gradle, so of course let's create a Gradle project.
■ Project creation screen Please set the Project SDK to 13.
Specify GroupId and ArtifactId on the next screen.
The next screen is where you set up your project, but I basically don't mess with it. All you have to do is make sure your Gradle JVM is 13.
After specifying the folder to be used on the next screen, the project will be created. Let's wait for a while until the various processes are completed.
** Add ** the following part to build.gradle. I haven't edited anything that isn't written.
build.gradle
plugins {
id 'application'
id 'org.openjfx.javafxplugin' version '0.0.8'
}
dependencies {
//This runtimeOnly group is for making cross-platform jars.
//You can reduce the size of the jar file by deleting unnecessary ones.
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) }
}
}
■ Now it looks like this (the lower part is a little cut)
The sample code was borrowed from OpenJFX Official.
src/main/java/maru/test/Launcher.java
package maru.test;
import javafx.application.Application;
public class Launcher {
public static void main(String... args){
Application.launch(MainApp.class);
}
}
src/main/java/maru/test/MainApp.java
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();
}
}
src/main/java/maru/test/FXMLController.java
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 + ".");
}
}
src/main/resources/maru/test/scene.fxml
<?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>
src/main/resources/maru/test/styles.css
.label {
-fx-text-fill: blue;
}
■ Like this
Click Gradle in the upper right corner and run Tasks> build> build. Once that's done, run Tasks> application> run a little above.
■ This is If you see something like this, you're successful!
■ "Like this"
I think you have a jar file in build / libs /
.
~~ This jar file is a fat jar (a jar file that also contains libraries), so it should work on anyone's PC. ~~
** I'm sorry I probably lied. If you want fat Jar, add shadow. ** **
Please change the place surrounded by <>
to your liking.
Only the parts that depend on the folder structure are extracted.
file name | |
---|---|
build.gradle | 2 places |
Launcher.java | One place |
MainApp.java | 2 places |
scene.fxml | One place |
build.gradle
mainClassName = '<Classes for launchers that do not inherit from the Application class>'
jar {
manifest {
attributes 'Main-Class': '<Same as mainClasName above>'
}
}
Launcher.java
public static void main(String... args){
Application.launch(<A class that inherits from the Application class>.class);
}
MainApp.java
@Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("<fxml file>"));
scene.getStylesheets().add(getClass().getResource("<css file>").toExternalForm());
}
scene.fxml
<StackPane (Omission) fx:controller="<Controller class>">
Probably over. I'm sorry if there is an oversight. .. ..
how was it? Wasn't it easier than I expected?
By the way, SceneBuilder is convenient for building screens. You can also do this by setting IntelliJ IDEA.
■ Such a thing I think this has lowered the hurdles for GUI application development. Enjoy a good GUI application life!
Recommended Posts