Layout Panes

Paul Ngugi - Jun 20 - - Dev Community

JavaFX provides many types of panes for automatically laying out nodes in a desired location and size. JavaFX provides many types of panes for organizing nodes in a container, as shown in Table below. You have used the layout panes Pane, StackPane, and HBox in the preceding sections for containing nodes. This section introduces the panes in more details.

Image description

You have used the Pane in here, ShowCircle.java. A Pane is usually used as a canvas for displaying shapes. Pane is the base class for all specialized panes. You have used a specialized pane StackPane in here, ButtonInPane.java. Nodes are placed in the center of a StackPane. Each pane contains a list for holding nodes in the pane. This list is an instance of ObservableList, which can be obtained using pane’s getChildren() method. You can use the add(node) method to add an element to the list, use addAll(node1, node2, ...) to add a variable number of nodes to the pane.

FlowPane

FlowPane arranges the nodes in the pane horizontally from left to right or vertically from top to bottom in the order in which they were added. When one row or one column is filled, a new row or column is started. You can specify the way the nodes are placed horizontally or vertically using one of two constants: Orientation.HORIZONTAL or Orientation.VERTICAL. You can also specify the gap between the nodes in pixels. The class diagram for FlowPane is shown in Figure below.

Image description

Data fields alignment, orientation, hgap, and vgap are binding properties. Each binding property in JavaFX has a getter method (e.g., getHgap()) that returns its value, a setter method (e.g., sethGap(double)) for setting a value, and a getter method that returns the property itself (e.g., hGapProperty()). For a data field of ObjectProperty type, the value getter method returns a value of type T and the property getter method returns a property value of type ObjectProperty.

The program below gives a program that demonstrates FlowPane. The program adds labels and text fields to a FlowPane.

Image description

The program creates a FlowPane (line 15) and sets its padding property with an Insets object (line 16). An Insets object specifies the size of the border of a pane. The constructor Insets(11, 12, 13, 14) creates an Insets with the border sizes for top (11), right (12), bottom (13), and left (14) in pixels, as shown in Figure below. You can also use the constructor Insets(value) to create an Insets with the same value for all four sides. The hGap and vGap properties are in lines 17–18 to specify the horizontal gap and vertical gap between two nodes in the pane, as shown in Figure below.

Image description

Each FlowPane contains an object of ObservableList for holding the nodes. This list can be obtained using the getChildren() method (line 21). To add a node into a FlowPane is to add it to this list using the add(node) or addAll(node1, node2, ...) method. You can also remove a node from the list using the remove(node) method or use the removeAll() method to remove all nodes from the pane. The program adds the labels and text fields into the pane (lines 21–24). Invoking tfMi.setPrefColumnCount(1) sets the preferred column count to 1 for the MI text field (line 23). The program declares an explicit reference tfMi for a TextField object for MI. The explicit reference is necessary, because we need to reference the object directly to set its prefColumnCount property.

The program adds the pane to the scene (line 27), sets the scene in the stage (line 29), and displays the stage (line 30). Note that if you resize the window, the nodes are automatically rearranged to fit in the pane. In Figure below (a), the first row has three nodes, but in Figure below (b), the first row has four nodes, because the width has been increased.

Image description

Suppose you wish to add the object tfMi to a pane ten times; will ten text fields appear in the pane? No, a node such as a text field can be added to only one pane and once. Adding a node to a pane multiple times or to different panes will cause a runtime error. A node can be placed only in one pane. Therefore, the relationship between a pane and a node is the composition denoted by a filled diamond.

GridPane

A GridPane arranges nodes in a grid (matrix) formation. The nodes are placed in the specified column and row indices. The class diagram for GridPane is shown in Figure below.

Image description

The program below gives a program that demonstrates GridPane, as shown in Figure below.

Image description



package application;
import javafx.application.Application;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;

public class ShowGridPane extends Application {
    @Override // Override the start method in the Application class
    public void start(Stage primaryStage) {
        // Create a pane and set its properties
        GridPane pane = new GridPane();
        pane.setAlignment(Pos.CENTER);
        pane.setPadding(new Insets(11.5, 12.5, 13.5, 14.5));
        pane.setHgap(5.5);
        pane.setVgap(5.5);

        // Place nodes in the pane
        pane.add(new Label("First Name"), 0, 0);
        pane.add(new TextField(), 1, 0);
        pane.add(new Label("MI:"), 0, 1);
        pane.add(new TextField(), 1, 1);
        pane.add(new Label("Last Name"), 0, 2);
        pane.add(new TextField(), 1, 2);
        Button btAdd = new Button("Add Name");
        pane.add(btAdd, 1, 3);
        GridPane.setHalignment(btAdd, HPos.RIGHT);

        // Create a scene and place it in the stage
        Scene scene = new Scene(pane);
        primaryStage.setTitle("ShowGridPane"); // Set the stage title
        primaryStage.setScene(scene); // Place the scene in the stage
        primaryStage.show(); // Display the stage
    }

    public static void main(String[] args) {
        Application.launch(args);
    }
}



Enter fullscreen mode Exit fullscreen mode

The program creates a GridPane (line 18) and sets its properties (line 19–22). The alignment is set to the center position (line 19), which causes the nodes to be placed in the center of the grid pane. If you resize the window, you will see the nodes remains in the center of the grid pane.

The program adds the label in column 0 and row 0 (line 25). The column and row index starts from 0. The add method places a node in the specified column and row. Not every cell in the grid needs to be filled. A button is placed in column 1 and row 3 (line 32), but there are no nodes placed in column 0 and row 3. To remove a node from a GridPane, use pane.getChildren().remove(node). To remove all nodes, use pane.getChildren().removeAll().

The program invokes the static setHalignment method to align the button right in the cell (line 33).

Note that the scene size is not set (line 36). In this case, the scene size is automatically computed according to the sizes of the nodes placed inside the scene.

BorderPane

A BorderPane can place nodes in five regions: top, bottom, left, right, and center, using the setTop(node), setBottom(node), setLeft(node), setRight(node), and setCenter(node) methods. The class diagram for GridPane is shown in Figure below.

Image description

The program below gives a program that demonstrates BorderPane. The program places five buttons in the five regions of the pane, as shown in Figure below.



package application;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class ShowBorderPane extends Application {
    @Override // Override the start method in the Application class
    public void start(Stage primaryStage) {
        // Create a pane and set its properties
        BorderPane pane = new BorderPane();

        // Place nodes in the pane
        pane.setTop(new CustomPane("Top"));
        pane.setRight(new CustomPane("Right"));
        pane.setBottom(new CustomPane("Buttom"));
        pane.setLeft(new CustomPane("Left"));
        pane.setCenter(new CustomPane("Center"));

        // Create a scene and place it in the stage
        Scene scene = new Scene(pane);
        primaryStage.setTitle("ShowBorderPane"); // Set the stage title
        primaryStage.setScene(scene); // Place the scene in the stage
        primaryStage.show(); // Display the stage
    }

    public static void main(String[] args) {
        Application.launch(args);
    }
}

// Define a custom pane to hold a label in the center of the pane
class CustomPane extends StackPane{
    public CustomPane(String title) {
        getChildren().add(new Label(title));
        setStyle("-fx-border-color: red");
        setPadding(new Insets(11.5, 12.5, 13.5, 14.5));
    }
}



Enter fullscreen mode Exit fullscreen mode

Image description

The program defines CustomPane that extends StackPane (line 36). The constructor of CustomPane adds a label with the specified title (line 38), sets a style for the border color, and sets a padding using insets (line 40).

The program creates a BorderPane (line 14) and places five instances of CustomPane into five regions of the border pane (lines 17–21). Note that a pane is a node. So a pane can be added into another pane. To remove a node from the top region, invoke setTop(null). If a region is not occupied, no space will be allocated for this region.

HBox and VBox

An HBox lays out its children in a single horizontal row. A VBox lays out its children in a single vertical column. Recall that a FlowPane can lay out its children in multiple rows or multiple columns, but an HBox or a VBox can lay out children only in one row or one column. The class diagrams for HBox and VBox are shown in Figures below.

Image description

Image description

The program below gives a program that demonstrates HBox and VBox. The program places two buttons in an HBox and five labels in a VBox, as shown in Figure below.



package application;
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.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;

public class ShowHBoxVBox extends Application {
    @Override // Override the start method in the Application class
    public void start(Stage primaryStage) {
        // Create a pane and set its properties
        BorderPane pane = new BorderPane();

        // Place nodes in the pane
        pane.setTop(getHBox());
        pane.setLeft(getVBox());

        // Create a scene and place it in the stage
        Scene scene = new Scene(pane);
        primaryStage.setTitle("ShowHBoxVBox"); // Set the stage title
        primaryStage.setScene(scene); // Place the scene in the stage
        primaryStage.show(); // Display the stage
    }

    private HBox getHBox() {
        HBox hBox = new HBox(15);
        hBox.setPadding(new Insets(15, 15, 15, 15));
        hBox.setStyle("-fx-background-color: gold");
        hBox.getChildren().add(new Button("Computer Science"));
        hBox.getChildren().add(new Button("Chemistry"));
        ImageView imageView = new ImageView(new Image("file:/C:/Users/Paul/development/MyJavaFX/src/application/image/ke.jpg"));
        hBox.getChildren().add(imageView);
        return hBox;
    }

    private VBox getVBox() {
        VBox vBox = new VBox(15);
        vBox.setPadding(new Insets(15, 15, 15, 15));
        vBox.getChildren().add(new Label("Courses"));

        Label[] courses = {new Label("CSCI 1301"), new Label("CSCI 1302"), new Label("CSCI 2410"), new Label("CSCI 3720")};

        for(Label course: courses) {
            VBox.setMargin(course, new Insets(0, 0, 0, 15));
            vBox.getChildren().add(course);
        }

        return vBox;
    }

    public static void main(String[] args) {
        Application.launch(args);
    }
}



Enter fullscreen mode Exit fullscreen mode

Image description

The program defines the getHBox() method. This method returns an HBox that contains two buttons and an image view (lines 31–40). The background color of the HBox is set to gold using Java CSS (line 35). The program defines the getVBox() method. This method returns a VBox that contains five labels (lines 42–55). The first label is added to the VBox in line 45 and the other four are added in line 51. The setMargin method is used to set a node’s margin when placed inside the VBox (line 50).

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .