Первая программа на JavaFX
Первая программа на JavaFX
Где применяют JavaFX
JavaFX (OpenJFX) — рекомендуемый стек для новых desktop-приложений на Java: CSS, FXML, анимации, TableView, диалоги. С Java 11 библиотека подключается через Maven или Gradle; в JDK «из коробки» её уже нет.
Мы соберём «Конвертер °C → °F» и разберём Application.launch() — без него окно не останется на экране, как mainloop() в Tkinter или SwingUtilities.invokeLater + видимое окно в Swing.
Теория: 311.md. Элементы UI по рецептам: 3112.md. Swing без зависимостей: Практические примеры — Swing.
Что получится
Поле ввода, кнопки «Перевести» и «Выход», метка результата; Enter в поле вызывает расчёт.
Подготовка проекта (Maven)
Минимальный pom.xml для Java 17 и OpenJFX 21:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>fx-demo</artifactId>
<version>1.0.0</version>
<properties>
<maven.compiler.release>17</maven.compiler.release>
<javafx.version>21.0.2</javafx.version>
</properties>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>${javafx.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.8</version>
<configuration>
<mainClass>com.example.HelloFx</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
Запуск из каталога проекта:
mvn javafx:run
Подробнее о структуре каталогов — Структуры проекта.
Минимальное окно
package com.example;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.stage.Stage;
public class HelloFx extends Application {
@Override
public void start(Stage stage) {
stage.setTitle("Привет, JavaFX");
stage.setScene(new Scene(new Label("Окно работает"), 320, 120));
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Разбор:
Application— точка входа JavaFX; платформа вызываетstart(Stage).Stage— окно;Scene— содержимое с корневым узлом и размером.launch(args)запускает UI-поток и цикл событий; безshow()окно не видно.
Конвертер температуры
package com.example;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class ConverterApp extends Application {
private TextField celsiusField;
private Label resultLabel;
private void convert() {
String raw = celsiusField.getText().trim().replace(',', '.');
try {
double celsius = Double.parseDouble(raw);
double fahrenheit = celsius * 9 / 5 + 32;
resultLabel.setText(String.format("%.1f °C = %.1f °F", celsius, fahrenheit));
} catch (NumberFormatException ex) {
Alert alert = new Alert(Alert.AlertType.ERROR);
alert.setTitle("Ошибка");
alert.setHeaderText(null);
alert.setContentText("Введите число, например 25");
alert.showAndWait();
}
}
@Override
public void start(Stage stage) {
GridPane grid = new GridPane();
grid.setHgap(10);
grid.setVgap(10);
grid.setPadding(new Insets(16));
grid.setAlignment(Pos.CENTER);
grid.add(new Label("Температура (°C):"), 0, 0);
celsiusField = new TextField();
celsiusField.setPromptText("25");
celsiusField.setPrefColumnCount(8);
grid.add(celsiusField, 1, 0);
resultLabel = new Label("—");
grid.add(resultLabel, 0, 1, 2, 1);
Button convertBtn = new Button("Перевести");
convertBtn.setOnAction(e -> convert());
Button exitBtn = new Button("Выход");
exitBtn.setOnAction(e -> stage.close());
HBox buttons = new HBox(8, convertBtn, exitBtn);
buttons.setAlignment(Pos.CENTER);
grid.add(buttons, 0, 2, 2, 1);
celsiusField.setOnKeyPressed(e -> {
if (e.getCode() == KeyCode.ENTER) {
convert();
}
});
Scene scene = new Scene(grid, 340, 160);
stage.setTitle("Конвертер температуры");
stage.setResizable(false);
stage.setScene(scene);
stage.show();
celsiusField.requestFocus();
}
public static void main(String[] args) {
launch(args);
}
}
Разбор:
convert()читает текст поля, парсит число и обновляетresultLabel.NumberFormatExceptionперехватывает нечисловой ввод;Alertпоказывает сообщение об ошибке.GridPaneвыравнивает метки и поля в сетке;HBoxгруппирует кнопки в ряд.setOnActionиsetOnKeyPressedсKeyCode.ENTER— два способа вызвать одну логику.
GridPane и VBox
GridPane— таблица строк и столбцов; удобен для форм «метка | поле».VBox/HBox— вертикальный или горизонтальный стек элементов.
В одном Parent у каждого дочернего узла одна позиция; для сложных форм вкладывают панели друг в друга.
Диалоги и меню (кратко)
Выбор файла:
import javafx.stage.FileChooser;
FileChooser chooser = new FileChooser();
chooser.setTitle("Выберите файл");
chooser.getExtensionFilters().add(
new FileChooser.ExtensionFilter("Текст", "*.txt")
);
java.io.File file = chooser.showOpenDialog(stage);
if (file != null) {
// чтение file
}
Меню:
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
MenuBar menuBar = new MenuBar();
Menu fileMenu = new Menu("Файл");
MenuItem exitItem = new MenuItem("Выход");
exitItem.setOnAction(e -> stage.close());
fileMenu.getItems().add(exitItem);
menuBar.getMenus().add(fileMenu);
import javafx.scene.layout.BorderPane;
BorderPane root = new BorderPane();
root.setTop(menuBar);
root.setCenter(grid);
stage.setScene(new Scene(root, 340, 200));
Частые ошибки
| Симптом | Причина |
|---|---|
| Окно «мигает» и закрывается | Нет launch() или show() |
Module javafx.controls not found | OpenJFX не в classpath / Maven |
IllegalStateException: Not on FX application thread | UI меняют из фонового потока |
| Интерфейс «зависает» | Долгая работа в setOnAction — вынесите в Task |
Error: JavaFX runtime components are missing | Запуск java без --module-path OpenJFX |
Что попробовать
- Перепишите форму на
VBox: метка, поле, результат, ряд кнопок. - Добавьте CSS:
scene.getStylesheets().add(".../app.css")и класс-fx-font-size. - Сохраните результат в файл через
FileChooser.showSaveDialog. - Вынесите разметку в FXML — см. 311.md.
Дальше
| Цель | Материал |
|---|---|
| Справочник API | 3112.md |
| Swing в JDK без Maven | 131.md — Swing |
| Потоки и UI | JVM, память и потоки |
| Теория десктопа | Архитектура десктопных приложений · 112.md · раздел «Десктопные приложения» |
См. также
Другие статьи этого же раздела в боковом меню (как на странице "О разделе"). Основы Java - устройство JDK/JVM, модель компиляции и базовые принципы платформонезависимого выполнения. Java — объектно-ориентированный язык общего назначения с принципом «напиши один раз, запускай в любом месте». Набор советов, правил, принципов и обычаев в разработке на этом языке. История Java — от проекта Green и Oak до OpenJDK, LTS-релизов и современной платформы (модули, records, виртуальные потоки). Библиотеки, фреймворки, инструменты сборки, тестирования, развёртывания и мониторинга. Что такое пакет и пакетная структура, как собираются проекты на Java. Справочник-шпаргалка по конфигурациям в Java — типы, синтаксис, стандартная библиотека, типовые паттерны. Не заменяет пошаговое обучение. Учебный курс — раздел. Гайд по установке и настройке с написанием первой программы и её запуском. Практические примеры — консольные утилиты, композиция классов и первое Swing-приложение. Точки останова, пошаговое выполнение, панели Variables и Call Stack — практика отладки в IntelliJ IDEA. Кавычки, точки, запятые, скобки и прочие знаки препинания. Это полный справочник всех ключевых слов языка Java, включая основные, контекстные и зарезервированные слова.Основы языка Java
Что требуется знать перед началом изучения языка программирования Java
Рекомендации по разработке на Java
История языка Java
Экосистема Java-приложений
Структура и сборки Java-проектов
Справочник по конфигурациям в Java
Первая программа на Java
Простые приложения на Java
Отладка Java-кода в IDE
Синтаксис и пунктуация в Java
Ключевые слова в Java