Справочник по JavaFX и Swing — элементы UI
Пошаговые рецепты для JavaFX (OpenJFX) и Swing. Каркас JavaFX — Первая программа на JavaFX; каркас Swing и полные программы с построчным разбором — Lab — Java Swing. Теория — JavaFX и GUI. Имена элементов — Архитектура десктопных приложений; EDT и фоновые задачи — Особенности разработки десктопных приложений.
Как пользоваться (JavaFX)
- В
start(Stage stage)создайте корневой контейнер (VBox,GridPaneилиBorderPane). - Скопируйте рецепт элемента и добавьте узел в контейнер:
box.getChildren().add(node)илиgrid.add(node, col, row). - Прикрепите сцену:
stage.setScene(new Scene(root, w, h)); stage.show();
UI меняют только в JavaFX Application Thread; из фона — Platform.runLater(() -> { ... }).
JavaFX
Главное окно (Stage + Scene)
Код ITЗагрузка примера кода…
Контейнер (VBox / GridPane / BorderPane)
Код ITЗагрузка примера кода…
Label (метка)
import javafx.scene.control.Label;
Label label = new Label("Имя пользователя:");
label.setStyle("-fx-font-weight: bold;");
Label dynamic = new Label();
dynamic.setText("Готово");
// или label.textProperty().bind(otherProperty);
box.getChildren().add(label);
TextBox — однострочный (TextField)
import javafx.scene.control.TextField;
TextField field = new TextField();
field.setPromptText("Введите имя");
field.setPrefColumnCount(24);
String value = field.getText().trim();
field.clear();
field.setText("по умолчанию");
field.setOnAction(e -> submit()); // Enter
grid.add(field, 1, 0);
TextBox — многострочный (TextArea)
import javafx.scene.control.TextArea;
TextArea area = new TextArea();
area.setPrefRowCount(6);
area.setWrapText(true);
String text = area.getText();
area.clear();
grid.add(area, 0, 1, 2, 1);
Поле пароля (PasswordField)
import javafx.scene.control.PasswordField;
PasswordField pwd = new PasswordField();
String password = pwd.getText();
grid.add(pwd, 1, 2);
Button (кнопка)
import javafx.scene.control.Button;
Button save = new Button("Сохранить");
save.setOnAction(e -> onSave());
save.setDefaultButton(true); // Enter в форме
save.setCancelButton(false);
box.getChildren().add(save);
CheckBox (флажок)
import javafx.scene.control.CheckBox;
CheckBox notify = new CheckBox("Уведомления");
notify.setSelected(true);
notify.selectedProperty().addListener((obs, oldVal, selected) -> { /* ... */ });
boolean on = notify.isSelected();
RadioButton (переключатель)
import javafx.scene.control.RadioButton;
import javafx.scene.control.ToggleGroup;
ToggleGroup roles = new ToggleGroup();
RadioButton user = new RadioButton("Пользователь");
RadioButton admin = new RadioButton("Админ");
user.setToggleGroup(roles);
admin.setToggleGroup(roles);
user.setSelected(true);
String role = ((RadioButton) roles.getSelectedToggle()).getText();
ComboBox (выпадающий список)
import javafx.scene.control.ComboBox;
import javafx.collections.FXCollections;
ComboBox<String> combo = new ComboBox<>(FXCollections.observableArrayList("Работа", "Личное"));
combo.getSelectionModel().selectFirst();
combo.setEditable(false);
String choice = combo.getValue();
box.getChildren().add(combo);
DatePicker (выбор даты)
import javafx.scene.control.DatePicker;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
DatePicker picker = new DatePicker(LocalDate.now());
LocalDate date = picker.getValue();
String formatted = date != null
? date.format(DateTimeFormatter.ofPattern("dd.MM.yyyy"))
: "—";
grid.add(picker, 1, 3);
ListView (список)
import javafx.scene.control.ListView;
import javafx.collections.FXCollections;
ListView<String> list = new ListView<>(FXCollections.observableArrayList("A", "B", "C"));
list.getSelectionModel().selectedItemProperty().addListener((obs, o, item) -> {
if (item != null) System.out.println(item);
});
list.getItems().add("D");
VBox.setVgrow(list, Priority.ALWAYS);
DataGrid (TableView)
Код ITЗагрузка примера кода…
ProgressBar (индикатор прогресса)
import javafx.scene.control.ProgressBar;
import javafx.scene.control.ProgressIndicator;
ProgressBar bar = new ProgressBar(0.0); // 0.0 .. 1.0
bar.setProgress(0.5);
ProgressIndicator spin = new ProgressIndicator(-1); // неопределённый
box.getChildren().addAll(bar, spin);
Slider (ползунок)
import javafx.scene.control.Slider;
Slider slider = new Slider(0, 100, 50);
slider.setShowTickLabels(true);
slider.valueProperty().addListener((obs, o, v) -> label.setText(String.valueOf(v.intValue())));
double v = slider.getValue();
Timeline (анимация свойств)
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.util.Duration;
Timeline timeline = new Timeline(
new KeyFrame(Duration.ZERO, e -> slider.setValue(0)),
new KeyFrame(Duration.seconds(2.5), new KeyValue(slider.valueProperty(), 1))
);
timeline.setOnFinished(e -> statusLabel.setText("Готово"));
timeline.play();
Анимация выполняется в JavaFX Application Thread; для длительной работы без блокировки UI используйте Task + Platform.runLater. Пример в контексте ProgressBar — Первая программа на JavaFX — вкладка "Прогресс".
Поле поиска (фильтр)
TextField search = new TextField();
search.setPromptText("Поиск…");
search.textProperty().addListener((obs, old, query) -> {
list.getItems().setAll(allItems.stream()
.filter(s -> s.toLowerCase().contains(query.toLowerCase()))
.toList());
});
Вкладки (TabPane)
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
TabPane tabs = new TabPane();
Tab general = new Tab("Общее", new Label("Содержимое"));
Tab settings = new Tab("Настройки");
settings.setContent(new VBox(new CheckBox("Опция")));
general.setClosable(false);
tabs.getTabs().addAll(general, settings);
BorderPane.setMargin(tabs, new Insets(8));
root.setCenter(tabs);
MenuBar (меню)
import javafx.scene.control.*;
MenuBar menuBar = new MenuBar();
Menu file = new Menu("Файл");
MenuItem open = new MenuItem("Открыть");
open.setOnAction(e -> openFile());
file.getItems().addAll(open, new SeparatorMenuItem(), new MenuItem("Выход"));
menuBar.getMenus().add(file);
root.setTop(menuBar);
ToolBar (панель инструментов)
import javafx.scene.control.ToolBar;
ToolBar toolBar = new ToolBar(
new Button("Новый"),
new Separator(),
new Button("Сохранить")
);
toolBar.getItems().forEach(node -> {
if (node instanceof Button b) b.setOnAction(e -> { /* ... */ });
});
root.setTop(toolBar);
StatusBar (строка состояния)
Label status = new Label("Готово");
status.setMaxWidth(Double.MAX_VALUE);
status.setStyle("-fx-padding: 4 8; -fx-background-color: #eee;");
HBox.setHgrow(status, Priority.ALWAYS);
HBox statusBar = new HBox(status);
root.setBottom(statusBar);
status.setText("Сохранено");
ScrollPane (прокрутка)
import javafx.scene.control.ScrollPane;
VBox content = new VBox(/* много виджетов */);
ScrollPane scroll = new ScrollPane(content);
scroll.setFitToWidth(true);
VBox.setVgrow(scroll, Priority.ALWAYS);
box.getChildren().add(scroll);
Диалоги и FileChooser
import javafx.scene.control.Alert;
import javafx.stage.FileChooser;
new Alert(Alert.AlertType.INFORMATION, "Готово").showAndWait();
Alert confirm = new Alert(Alert.AlertType.CONFIRMATION, "Удалить файл?");
confirm.showAndWait().filter(r -> r == ButtonType.OK).ifPresent(r -> delete());
FileChooser fc = new FileChooser();
fc.getExtensionFilters().add(new FileChooser.ExtensionFilter("JSON", "*.json"));
File f = fc.showOpenDialog(stage);
File save = fc.showSaveDialog(stage);
Tooltip (подсказка)
import javafx.scene.control.Tooltip;
Button btn = new Button("?");
Tooltip.install(btn, new Tooltip("Сохранить на диск"));
Context menu (контекстное меню)
ContextMenu menu = new ContextMenu(
new MenuItem("Копировать"),
new MenuItem("Вставить")
);
list.setContextMenu(menu);
// или для произвольного узла:
node.setOnContextMenuRequested(e -> menu.show(node, e.getScreenX(), e.getScreenY()));
Дочернее окно (Stage)
Stage dialog = new Stage();
dialog.initOwner(primaryStage);
dialog.initModality(Modality.WINDOW_MODAL);
dialog.setScene(new Scene(new VBox(new Label("Настройки")), 320, 200));
dialog.showAndWait();
Swing
Каркас — Простые приложения на Java — Swing. Полные программы с разбором строк — Lab — Java Swing. Все изменения UI — в EDT: SwingUtilities.invokeLater(() -> { ... }).
Как пользоваться (Swing)
- Скопируйте обязательный каркас в файл
ИмяКласса.java. - Добавьте рецепт элемента из раздела ниже (
JButton,JTextField…). - Для лабораторной возьмите готовый пример из Lab (кнопка, форма, список задач) и сверьте таблицу "Разбор построчно".
- Долгие операции не кладите в
ActionListener— см. Особенности разработки десктопных приложений иSwingWorkerв JavaFX и GUI.
Главное окно (JFrame)
import javax.swing.*;
JFrame frame = new JFrame("Моё приложение");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(640, 480);
frame.setLocationRelativeTo(null);
JPanel root = new JPanel(new BorderLayout(8, 8));
frame.add(root);
frame.setVisible(true);
Label — JLabel
JLabel label = new JLabel("Имя:");
root.add(label, BorderLayout.NORTH);
label.setText("Обновлено");
TextField — JTextField
JTextField field = new JTextField(20);
String v = field.getText();
field.setText("по умолчанию");
panel.add(field);
TextArea — JTextArea
JTextArea area = new JTextArea(8, 30);
area.setLineWrap(true);
panel.add(new JScrollPane(area));
Password — JPasswordField
JPasswordField pwd = new JPasswordField(16);
char[] pass = pwd.getPassword();
Button — JButton
JButton btn = new JButton("Сохранить");
btn.addActionListener(e -> save());
panel.add(btn);
CheckBox / RadioButton
JCheckBox chk = new JCheckBox("Включено", true);
JRadioButton a = new JRadioButton("A");
JRadioButton b = new JRadioButton("B");
ButtonGroup group = new ButtonGroup();
group.add(a);
group.add(b);
ComboBox — JComboBox
JComboBox<String> combo = new JComboBox<>(new String[]{"Работа", "Личное"});
String item = (String) combo.getSelectedItem();
List — JList
JList<String> list = new JList<>(new String[]{"A", "B", "C"});
list.addListSelectionListener(e -> {
if (!e.getValueIsAdjusting()) System.out.println(list.getSelectedValue());
});
panel.add(new JScrollPane(list));
Table — JTable
import javax.swing.table.DefaultTableModel;
String[] cols = {"Имя", "Возраст"};
Object[][] data = {{"Алиса", 30}};
JTable table = new JTable(new DefaultTableModel(data, cols));
panel.add(new JScrollPane(table));
ProgressBar — JProgressBar
JProgressBar bar = new JProgressBar(0, 100);
bar.setValue(50);
bar.setIndeterminate(true);
Tabs — JTabbedPane
JTabbedPane tabs = new JTabbedPane();
tabs.addTab("Общее", new JLabel("Контент"));
tabs.addTab("Настройки", new JPanel());
root.add(tabs, BorderLayout.CENTER);
Menu — JMenuBar
JMenuBar bar = new JMenuBar();
JMenu file = new JMenu("Файл");
JMenuItem exit = new JMenuItem("Выход");
exit.addActionListener(e -> frame.dispose());
file.add(exit);
bar.add(file);
frame.setJMenuBar(bar);
ToolBar — JToolBar
JToolBar toolBar = new JToolBar();
toolBar.add(new JButton("Новый"));
toolBar.setFloatable(false);
root.add(toolBar, BorderLayout.NORTH);
StatusBar
JLabel status = new JLabel(" Готово");
status.setBorder(BorderFactory.createLoweredBevelBorder());
root.add(status, BorderLayout.SOUTH);
Диалоги
JOptionPane.showMessageDialog(frame, "Текст");
int ok = JOptionPane.showConfirmDialog(frame, "Удалить?");
JFileChooser chooser = new JFileChooser();
if (chooser.showOpenDialog(frame) == JFileChooser.APPROVE_OPTION) {
File f = chooser.getSelectedFile();
}
Tooltip
btn.setToolTipText("Сохранить документ");
Context menu — JPopupMenu
JPopupMenu popup = new JPopupMenu();
popup.add(new JMenuItem("Копировать"));
list.setComponentPopupMenu(popup);
Частые ошибки
| Симптом | JavaFX | Swing |
|---|---|---|
package javafx… does not exist | Нет javafx.version в pom — Первая программа на JavaFX | — |
runtime components are missing | Запуск без --module-path — Первая программа на JavaFX | — |
| UI не обновляется из потока | Platform.runLater | SwingUtilities.invokeLater |
| Окно пустое | Нет stage.show() | Нет setVisible(true) |
| Module not found | OpenJFX в Maven / module path | — |
См. также
- JavaFX и GUI · Первая программа · Swing — практика · Lab — окна и кнопки · Tkinter — галерея
- Архитектура десктопа · раздел "Десктопные приложения" · Особенности разработки десктопных приложений