BorderPane и GridPane
VBox и HBox хороши для простых рядов. Для окна целиком удобнее BorderPane — каркас из пяти областей. А поля формы с подписями слева удобно выравнивать сеткой GridPane. Вместе они дадут основной экран записной книжки: список слева, форма в центре, кнопки внизу.
BorderPane — пять областей
| Метод | Область |
|---|---|
setTop(Node) | Верх на всю ширину |
setBottom(Node) | Низ на всю ширину |
setLeft(Node) | Левая панель |
setRight(Node) | Правая панель |
setCenter(Node) | Центр — забирает всё оставшееся место |
В каждую область кладут один узел, обычно контейнер. Пустые области места не занимают:
// src/main/java/com/example/notes/App.java — фрагмент start()
BorderPane root = new BorderPane();
root.setTop(header);
root.setLeft(listPane);
root.setCenter(form);
root.setBottom(buttons);
root.setPadding(new Insets(16));
BorderPane.setMargin(header, new Insets(0, 0, 12, 0));Своего расстояния между областями у BorderPane нет, поэтому отступ задают узлу: BorderPane.setMargin. Четыре числа Insets идут по часовой стрелке: сверху, справа, снизу, слева.
GridPane — сетка
GridPane раскладывает узлы по ячейкам. Метод add принимает узел, номер колонки и номер строки — именно в таком порядке, счёт с нуля:
// src/main/java/com/example/notes/App.java — фрагмент start()
GridPane form = new GridPane();
form.setHgap(8);
form.setVgap(8);
form.add(new Label("Заголовок:"), 0, 0);
form.add(new TextField(), 1, 0);
form.add(new Label("Текст:"), 0, 1);
form.add(new TextArea(), 1, 1);setHgap и setVgap — расстояния между колонками и строками. TextArea — многострочное поле.
Настройка колонок
Чтобы поля тянулись по ширине, а подписи сохраняли свой размер, колонкам задают правила ColumnConstraints:
// src/main/java/com/example/notes/App.java — фрагмент start()
ColumnConstraints labels = new ColumnConstraints();
labels.setMinWidth(Region.USE_PREF_SIZE);
ColumnConstraints fields = new ColumnConstraints();
fields.setHgrow(Priority.ALWAYS);
form.getColumnConstraints().addAll(labels, fields);Первое правило относится к колонке 0, второе — к колонке 1.
Экран целиком
// src/main/java/com/example/notes/App.java
package com.example.notes;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class App extends Application {
@Override
public void start(Stage stage) {
Label header = new Label("Мои заметки");
// слева — место для будущего списка заметок
VBox listPane = new VBox(new Label("Заметок пока нет"));
listPane.setPrefWidth(200);
GridPane form = new GridPane();
form.setHgap(8);
form.setVgap(8);
form.setPadding(new Insets(0, 0, 0, 16));
form.add(new Label("Заголовок:"), 0, 0);
form.add(new TextField(), 1, 0);
form.add(new Label("Текст:"), 0, 1);
form.add(new TextArea(), 1, 1);
ColumnConstraints labels = new ColumnConstraints();
labels.setMinWidth(Region.USE_PREF_SIZE);
ColumnConstraints fields = new ColumnConstraints();
fields.setHgrow(Priority.ALWAYS);
form.getColumnConstraints().addAll(labels, fields);
HBox buttons = new HBox(8, new Button("Добавить"), new Button("Удалить"));
buttons.setPadding(new Insets(12, 0, 0, 0));
BorderPane root = new BorderPane();
root.setTop(header);
root.setLeft(listPane);
root.setCenter(form);
root.setBottom(buttons);
root.setPadding(new Insets(16));
BorderPane.setMargin(header, new Insets(0, 0, 12, 0));
stage.setTitle("Заметки");
stage.setScene(new Scene(root, 640, 480));
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}В окне: сверху «Мои заметки», слева колонка шириной 200 пикселей с надписью «Заметок пока нет», справа от неё подписи «Заголовок:» и «Текст:» с полями, растянутыми до правого края. Кнопки «Добавить» и «Удалить» прижаты к низу окна.
Частая ошибка
Если не задать первой колонке setMinWidth(Region.USE_PREF_SIZE), широкое поле TextArea отнимет у неё место, и вместо подписей в окне будет многоточие .... Ошибки в терминале нет — проблема видна только на экране. Правило минимальной ширины говорит сетке не сжимать колонку меньше длины подписи.