BorderPane and GridPane
VBox and HBox are good for simple rows. For a whole window BorderPane is handier: a frame of five areas. And form fields with labels on the left line up nicely in a GridPane. Together they give the main notebook screen: a list on the left, a form in the center, buttons at the bottom.
BorderPane, five areas
| Method | Area |
|---|---|
setTop(Node) | The top, full width |
setBottom(Node) | The bottom, full width |
setLeft(Node) | The left panel |
setRight(Node) | The right panel |
setCenter(Node) | The center, takes all the remaining space |
Each area holds one node, usually a container. Empty areas take no space:
// src/main/java/com/example/notes/App.java — part of 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 has no gap between areas, so the spacing is set on a node with BorderPane.setMargin. The four Insets numbers go clockwise: top, right, bottom, left.
GridPane, a grid
GridPane arranges nodes in cells. The add method takes a node, a column index and a row index, in exactly that order, counting from zero:
// src/main/java/com/example/notes/App.java — part of start()
GridPane form = new GridPane();
form.setHgap(8);
form.setVgap(8);
form.add(new Label("Title:"), 0, 0);
form.add(new TextField(), 1, 0);
form.add(new Label("Text:"), 0, 1);
form.add(new TextArea(), 1, 1);setHgap and setVgap are the gaps between columns and rows. TextArea is a multi-line field.
Column settings
To make the fields stretch while the labels keep their size, give the columns ColumnConstraints rules:
// src/main/java/com/example/notes/App.java — part of start()
ColumnConstraints labels = new ColumnConstraints();
labels.setMinWidth(Region.USE_PREF_SIZE);
ColumnConstraints fields = new ColumnConstraints();
fields.setHgrow(Priority.ALWAYS);
form.getColumnConstraints().addAll(labels, fields);The first rule applies to column 0, the second to column 1.
The whole screen
// 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("My notes");
// on the left: room for the future list of notes
VBox listPane = new VBox(new Label("No notes yet"));
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("Title:"), 0, 0);
form.add(new TextField(), 1, 0);
form.add(new Label("Text:"), 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("Add"), new Button("Delete"));
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("Notes");
stage.setScene(new Scene(root, 640, 480));
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}The window shows "My notes" at the top, a 200-pixel column on the left with "No notes yet", and to its right the labels "Title:" and "Text:" with fields stretched to the right edge. The "Add" and "Delete" buttons sit at the bottom of the window.
Common mistake
If you do not give the first column setMinWidth(Region.USE_PREF_SIZE), the wide TextArea takes its space, and the labels turn into an ellipsis ... in the window. There is no error in the terminal; the problem is only visible on screen. The minimum width rule tells the grid not to shrink the column below the label length.