JavaFX#
JavaFX — это современная платформа для создания кроссплатформенных десктопных приложений на Java, предоставляющая богатый набор компонентов, эффектов, анимаций и инструментов. В отличие от устаревшего Swing, JavaFX предоставляет:
Современный API для создания UI
Поддержку аппаратного ускорения графики
Встроенную поддержку CSS для стилизации
FXML для декларативного описания интерфейсов
Поддержку MVVM паттерна
Пакет |
Версия |
Репозиторий |
Описание |
---|---|---|---|
openjdk-17-jdk |
17.0.13+11-2~deb12u1 |
extended |
Комплект разработки ПО на Java |
openjfx |
11.0.11+1-4 |
extended |
Платформа JavaFX/OpenJFX для графических приложений для Java |
maven |
3.8.7-1 |
extended |
Инструмент для автоматической сборки проектов на Java и др. языках |
gradle |
4.4.1-18+b1 |
extended |
Система для автоматической сборки проектов (в т.ч. на Java) |
Пакет |
Версия |
Репозиторий |
Описание |
---|---|---|---|
23.0.1 |
gluon |
Визуальные конструктор FXML файлов |
|
2.0 |
oracle |
Инструмент визуальной разработки FXML файлов |
|
11.2.2 |
github |
Дополнительные компоненты UI |
|
9.0.10 |
github |
Material Design компоненты |
Разработка пользовательского интерфейса с помощью Scene Builder (от Gluon)#
Пункт 1#
Установка OpenJDK:
sudo apt install openjdk-17-jdk
Пункт 2#
Для установки Scene Builder необходимо загрузить пакет по ссылке.
Примечание
Пакет libffi7 находится в зависимостях Scene Builder, он отдельно устанавливается по ссылке.
Пункт 3#
После установки Scene Builder необходимо запустить из меню пуск. Создать интерфейс можно перетаскиванием виджетов из панели. Файл сохраняется с расширением FXML.
Дополнительные компоненты#
Список виджетов можно расширить с помощью пакета ControlsFX. ControlsFX — это библиотека-надстройка над JavaFX, которая добавляет новые компоненты и улучшает стандартные.
Maven#
Для этого в проекте Maven необходимо в файле pom.xml указать следующие библиотеки:
<!-- JavaFX -->
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>17</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>17</version>
</dependency>
<!-- ControlsFX -->
<dependency>
<groupId>org.controlsfx</groupId>
<artifactId>controlsfx</artifactId>
<version>11.1.2</version>
</dependency>
После требуется обновить зависимости проекта:
mvn dependency:resolve
Примечание
Для обновления поврежденных зависимостей рекомендуется использовать команду выше с параметром -U. Подробнее об обновлении репозитория с помощью maven читайте в статье.
Gradle#
Если проект под управлением Gradle, необходимо в файле build.gradle задать следующие библиотеки:
dependencies {
// JavaFX
implementation 'org.openjfx:javafx-controls:17'
implementation 'org.openjfx:javafx-fxml:17'
// ControlsFX
implementation 'org.controlsfx:controlsfx:11.1.2'
}
После требуется обновить зависимости проекта:
gradle dependencies --refresh-dependencies
Создание JavaFX приложения с Maven#
Ниже представлен пример создания приложения, используя стандартные виджеты JavaFX. В пункте Создание JavaFX приложения с Gradle описано создание аналогичного приложения, с использованием контроллера и макета приложения с помощью FXML файла.
Пункт 1#
Установка OpenJDK:
sudo apt install openjdk-17-jdk
sudo apt install maven
Пункт 2#
Создание проекта и ручной переход в директорию javafx-userinfo-app:
mvn archetype:generate \
-DgroupId=com.example \
-DartifactId=javafx-userinfo-app \
-DarchetypeArtifactId=maven-archetype-quickstart \
-DinteractiveMode=false
Пункт 3#
Добавление зависимостей перезаписью pom.xml файла:
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<javafx.version>17.0.2</javafx.version>
</properties>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>${javafx.version}</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-graphics</artifactId>
<version>${javafx.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
</plugin>
<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.8</version>
<configuration>
<mainClass>com.example.App</mainClass>
</configuration>
</plugin>
</plugins>
</build>
Пункт 4#
Создание основного класса в src/main/java/com/example/App.java файле:
package com.example;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class App extends Application {
@Override
public void start(Stage primaryStage) {
Label label = new Label();
Button button = new Button("Узнать пользователя");
button.setOnAction(e -> {
if (button.getText().equals("Узнать пользователя")) {
String user = System.getProperty("user.name");
label.setText("Текущий пользователь: " + user);
button.setText("Очистить");
} else {
label.setText("");
button.setText("Узнать пользователя");
}
});
VBox root = new VBox(10, button, label);
Scene scene = new Scene(root, 300, 200);
primaryStage.setTitle("JavaFX App");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Пункт 5#
Сборка и запуск приложения:
mvn clean javafx:run
Сборка и упаковка#
Для упаковки JavaFX приложения рекомендуется создавать самодостаточный исполняемый JAR (fat-jar). На его основе создается deb-пакет с помощью утилиты из состава JDK jpackage.
Пункт 1#
Добавление плагина создания fat-jar:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.example.App</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
Пункт 2#
Сборка fat-jar (предварительно рекомендуется удалить файлы тестов из директории src/test/java/com/example):
mvn clean package
Пункт 3#
Создание deb-пакета (используя jpackage)
jpackage --input target/ \
--name javafx-userinfo-app \
--main-jar javafx-userinfo-app-1.0.jar \
--main-class com.example.App \
--type deb \
--java-options '--enable-preview' \
--runtime-image $JAVA_HOME
Создание JavaFX приложения с Gradle#
Ниже представлен пример создания приложения с использованием контроллера и макета приложения с помощью FXML файла. В пункте Создание JavaFX приложения с Maven описано создание аналогичного приложения без использования MVVM паттерна. Представлен вариант создания deb-пакета используя встроенные средства Gradle (требуемая версия <= 8.8), иначе можно воспользоваться jpackage, как описано выше.
Пункт 1#
Установка OpenJDK и Gradle 8.14 с помощью SDKMAN <https://sdkman.io/install/>__ (инструмент управления версиями пакетов):
sudo apt install openjdk-17-jdk
# Установка SDKMAN
curl -s "https://get.sdkman.io" | bash
source "$HOME/.sdkman/bin/sdkman-init.sh"
# Установка последнюю версию Gradle
sdk install gradle
# Проверка версии Gradle
gradle -v
Примечание
Для работы с Java 17+ рекомендуется Gradle 7.0+.
Пункт 2#
После создания каталога проекта необходимо выполнить генерацию шаблонного проекта в новой директории:
gradle init --type java-application
Обновление gradle до версии 8.8:
./gradlew wrapper --gradle-version 8.8
Пункт 3#
Добавление JavaFX в зависимости перезаписью build.gradle файла и добавление инструкции создания deb-пакета:
plugins {
id 'java'
id 'application'
id 'org.openjfx.javafxplugin' version '0.0.13' // Плагин JavaFX
// Плагины создания deb-пакета
id 'org.beryx.jlink' version '2.26.0'
id 'org.javamodularity.moduleplugin' version '1.8.12'
}
group 'com.example'
version '1.0'
repositories {
mavenCentral()
}
// Задание основных класса и модуля проекта (для deb-пакета)
application {
mainModule = 'com.example'
mainClass = 'com.example.MainApp'
}
javafx {
version = "17.0.2"
modules = [ 'javafx.controls', 'javafx.fxml' ]
}
dependencies {
implementation 'org.openjfx:javafx-controls:17'
implementation 'org.openjfx:javafx-fxml:17'
}
task createFatJar(type: Jar) {
manifest {
attributes 'Main-Class': 'com.example.MainApp'
}
archiveBaseName = 'user-info-app'
from {
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
}
with jar
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
// Инструкция сборки модулей и создания deb-пакета
jlink {
launcher {
name = 'App'
}
// Инструкция создания deb пакета
jpackage {
installerType = 'deb'
installerOptions = [
'--linux-menu-group', 'Development',
'--linux-shortcut'
]
}
}
Пункт 4#
Настройка module-info.java файла:
module com.example {
requires javafx.controls;
requires javafx.fxml;
opens com.example to javafx.fxml;
exports com.example;
}
Пункт 5#
Создание основного класса src/main/java/com/example/MainApp.java:
package com.example;
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 primaryStage) throws Exception {
FXMLLoader loader = new FXMLLoader(getClass().getResource("/com/example/main.fxml"));
Parent root = loader.load();
primaryStage.setTitle("User Info App");
primaryStage.setScene(new Scene(root, 300, 200));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Пункт 6#
Создание класса контроллера в src/main/java/com/example/UserInfoController.java файле:
package com.example;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
public class UserInfoController {
@FXML private Label infoLabel;
@FXML private Button actionButton;
@FXML
private void handleButtonAction() {
if (actionButton.getText().equals("Узнать пользователя")) {
String user = System.getProperty("user.name");
infoLabel.setText("Текущий пользователь: " + user);
actionButton.setText("Очистить");
} else {
infoLabel.setText("");
actionButton.setText("Узнать пользователя");
}
}
}
Пункт 7#
Создание интерфейса с помощью файла FXML src/main/resources/com/example/main.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<VBox xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="com.example.UserInfoController" spacing="10" alignment="CENTER">
<Button fx:id="actionButton" text="Узнать пользователя" onAction="#handleButtonAction"/>
<Label fx:id="infoLabel" />
</VBox>
Пункт 8#
Запуск приложения:
gradle clean run
Сборка и упаковка#
Создание deb-пакет с помощью сценария jpackage, прописанного в файле build.gradle:
./gradlew jpackage