Dr. Vatsal Shah
Subject Material

Java · JavaFX · Topic 4

JavaFX Layouts

Arrange controls with horizontal, vertical, grid, regional, flowing, stacked, and anchored layout panes.

Topic progress · 1 of 7 sections

Step 1 of 7

4.1 HBox

Learning objective

Arrange child nodes in one horizontal row.

Horizontal button row
HBox actions = new HBox(10);
actions.getChildren().addAll(saveButton, cancelButton);
actions.setAlignment(Pos.CENTER);
actions.setPadding(new Insets(15));

Useful HBox settings

  • setSpacing(double)
  • setAlignment(Pos)
  • setPadding(Insets)
  • HBox.setHgrow(node, Priority.ALWAYS)
HBoxDemo.java
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;

public class HBoxDemo extends Application {
    @Override
    public void start(Stage stage) {
        HBox root = new HBox(15,
                new Button("Save"), new Button("Cancel"));
        root.setAlignment(Pos.CENTER);
        stage.setScene(new Scene(root, 320, 140));
        stage.setTitle("HBox Demo");
        stage.show();
    }
    public static void main(String[] args) { launch(args); }
}
Expected result
Save and Cancel appear side by side in one centered horizontal row.
Check your understanding: Which constructor argument in new HBox(10, a, b) controls the space between children?

The value 10.

Step 2 of 7

4.2 VBox

Learning objective

Arrange child nodes in one vertical column.

Vertical form section
VBox form = new VBox(12,
        new Label("Student Login"),
        usernameField,
        passwordField,
        loginButton);
form.setPadding(new Insets(20));
VBoxDemo.java
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class VBoxDemo extends Application {
    @Override
    public void start(Stage stage) {
        VBox root = new VBox(10,
                new Label("Student Login"),
                new TextField(),
                new PasswordField(),
                new Button("Login"));
        root.setPadding(new Insets(20));
        stage.setScene(new Scene(root, 340, 230));
        stage.setTitle("VBox Demo");
        stage.show();
    }
    public static void main(String[] args) { launch(args); }
}
Expected result
The heading, fields, and Login button appear in one vertical column.
Check your understanding: Which layout is a natural choice for placing a heading above a form and buttons?

VBox.

Step 3 of 7

4.3 GridPane

Learning objective

Arrange nodes in rows and columns for aligned forms.

Two-column form
GridPane grid = new GridPane();
grid.setHgap(10);
grid.setVgap(10);
grid.setPadding(new Insets(20));

grid.add(new Label("Name"), 0, 0);
grid.add(nameField, 1, 0);
grid.add(new Label("Branch"), 0, 1);
grid.add(branchBox, 1, 1);
grid.add(submitButton, 1, 2);
GridPaneDemo.java
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;

public class GridPaneDemo extends Application {
    @Override
    public void start(Stage stage) {
        TextField name = new TextField();
        TextField enrollment = new TextField();
        Button submit = new Button("Submit");
        Label result = new Label();
        submit.setOnAction(e -> result.setText(
                name.getText() + " - " + enrollment.getText()));

        GridPane root = new GridPane();
        root.setHgap(10); root.setVgap(10);
        root.setPadding(new Insets(20));
        root.addRow(0, new Label("Name"), name);
        root.addRow(1, new Label("Enrollment"), enrollment);
        root.addRow(2, submit, result);
        stage.setScene(new Scene(root, 420, 220));
        stage.setTitle("GridPane Demo");
        stage.show();
    }
    public static void main(String[] args) { launch(args); }
}
Expected result
Labels and fields align in two columns.
Example: Vatsal - 23IT001
Check your understanding: In grid.add(nameField, 1, 0), what do 1 and 0 mean?

Column 1, row 0.

Step 4 of 7

4.4 BorderPane

Learning objective

Place content in top, bottom, left, right, and center regions.

Application shell
BorderPane root = new BorderPane();
root.setTop(menuBar);
root.setLeft(navigation);
root.setCenter(content);
root.setBottom(statusLabel);
BorderPane regions
RegionCommon use
TopMenu or heading
BottomStatus or action bar
LeftNavigation
RightTools or details
CenterMain content
BorderPaneDemo.java
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

public class BorderPaneDemo extends Application {
    @Override
    public void start(Stage stage) {
        BorderPane root = new BorderPane();
        root.setTop(new Label("Header"));
        root.setLeft(new Label("Navigation"));
        root.setCenter(new Label("Main Content"));
        root.setBottom(new Label("Status: Ready"));
        BorderPane.setAlignment(root.getTop(), Pos.CENTER);
        stage.setScene(new Scene(root, 440, 260));
        stage.setTitle("BorderPane Demo");
        stage.show();
    }
    public static void main(String[] args) { launch(args); }
}
Expected result
Header appears at the top, Navigation at the left, Main Content in the center, and Status at the bottom.
Check your understanding: Which BorderPane region grows to use the available middle area?

The center region.

Step 5 of 7

4.5 FlowPane

Learning objective

Flow child nodes into rows or columns and wrap them when space runs out.

Wrapping skill buttons
FlowPane skills = new FlowPane(10, 10);
skills.setPadding(new Insets(15));
skills.getChildren().addAll(
        new Button("Java"),
        new Button("Python"),
        new Button("Database"),
        new Button("Networks"));
FlowPaneDemo.java
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.FlowPane;
import javafx.stage.Stage;

public class FlowPaneDemo extends Application {
    @Override
    public void start(Stage stage) {
        FlowPane root = new FlowPane(10, 10);
        root.setPadding(new Insets(15));
        for (String skill : new String[]{"Java", "Python", "Database", "AI"}) {
            root.getChildren().add(new Button(skill));
        }
        stage.setScene(new Scene(root, 300, 180));
        stage.setTitle("FlowPane Demo");
        stage.show();
    }
    public static void main(String[] args) { launch(args); }
}
Expected result
Skill buttons flow from left to right and wrap when the window becomes narrow.
Check your understanding: What happens when a horizontal FlowPane becomes too narrow?

Its children wrap onto another row.

Step 6 of 7

4.6 StackPane

Learning objective

Overlay child nodes in the same layout area.

Overlay a label on a shape
Rectangle card = new Rectangle(240, 100, Color.LIGHTBLUE);
Label title = new Label("JavaFX");
StackPane banner = new StackPane(card, title);
StackPaneDemo.java
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

public class StackPaneDemo extends Application {
    @Override
    public void start(Stage stage) {
        Rectangle card = new Rectangle(240, 100, Color.LIGHTBLUE);
        Label title = new Label("JavaFX");
        StackPane root = new StackPane(card, title);
        stage.setScene(new Scene(root, 320, 180));
        stage.setTitle("StackPane Demo");
        stage.show();
    }
    public static void main(String[] args) { launch(args); }
}
Expected result
The text JavaFX is centered on top of a light-blue rectangle.
Check your understanding: Which pane is suitable for placing text over an image?

StackPane.

Step 7 of 7

4.7 AnchorPane

Learning objective

Anchor nodes to one or more edges and combine multiple layouts in a complete screen.

Anchor a control to the edges
AnchorPane pane = new AnchorPane(content, saveButton);
AnchorPane.setTopAnchor(content, 10.0);
AnchorPane.setLeftAnchor(content, 10.0);
AnchorPane.setRightAnchor(content, 10.0);
AnchorPane.setBottomAnchor(saveButton, 10.0);
AnchorPane.setRightAnchor(saveButton, 10.0);
NestedLayoutDemo.java
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;

public class NestedLayoutDemo extends Application {
    @Override
    public void start(Stage stage) {
        Label heading = new Label("Student Registration");
        HBox header = new HBox(heading);
        header.setAlignment(Pos.CENTER);
        header.setPadding(new Insets(12));

        TextField name = new TextField();
        ComboBox<String> branch = new ComboBox<>();
        branch.getItems().addAll("CSE", "IT", "EC");

        GridPane form = new GridPane();
        form.setHgap(10);
        form.setVgap(10);
        form.setPadding(new Insets(20));
        form.addRow(0, new Label("Name"), name);
        form.addRow(1, new Label("Branch"), branch);

        Label status = new Label("Ready");
        Button submit = new Button("Submit");
        Button clear = new Button("Clear");
        HBox actions = new HBox(10, submit, clear);
        actions.setAlignment(Pos.CENTER_RIGHT);
        actions.setPadding(new Insets(12));

        submit.setOnAction(e -> status.setText("Form submitted"));
        clear.setOnAction(e -> {
            name.clear();
            branch.getSelectionModel().clearSelection();
            status.setText("Form cleared");
        });

        BorderPane root = new BorderPane();
        root.setTop(header);
        root.setCenter(form);
        root.setBottom(new VBox(6, status, actions));

        stage.setScene(new Scene(root, 480, 300));
        stage.setTitle("Nested Layout Demo");
        stage.show();
    }

    public static void main(String[] args) {
        Application.launch(args);
    }
}
Expected result
A registration window opens with:
- Centered heading in an HBox
- Name and Branch fields in a GridPane
- Status and action buttons in nested VBox/HBox layouts
- All sections arranged by a BorderPane

Submit displays: Form submitted
Clear displays: Form cleared
AnchorPaneDemo.java
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;

public class AnchorPaneDemo extends Application {
    @Override
    public void start(Stage stage) {
        TextArea notes = new TextArea();
        Button save = new Button("Save");
        AnchorPane root = new AnchorPane(notes, save);
        AnchorPane.setTopAnchor(notes, 10.0);
        AnchorPane.setLeftAnchor(notes, 10.0);
        AnchorPane.setRightAnchor(notes, 10.0);
        AnchorPane.setBottomAnchor(notes, 50.0);
        AnchorPane.setRightAnchor(save, 10.0);
        AnchorPane.setBottomAnchor(save, 10.0);
        stage.setScene(new Scene(root, 420, 260));
        stage.setTitle("AnchorPane Demo");
        stage.show();
    }
    public static void main(String[] args) { launch(args); }
}
Expected result
The TextArea remains 10 pixels from the top, left, and right edges; Save remains at the bottom-right.
Check your understanding: Which calls keep a button ten pixels from the bottom-right corner?

AnchorPane.setBottomAnchor(button, 10.0) and AnchorPane.setRightAnchor(button, 10.0).