JavaFX Tutorial: Advanced Layouts

How to organize and place GUI components in a JavaFX application using advanced layouts.



In a previous article, we looked at some basic JavaFX layouts. Now it's time to consider the rest of the available layouts.



  1. JavaFX Tutorial: Getting Started
  2. JavaFX Tutorial: Hello world!
  3. JavaFX Tutorial: FXML and SceneBuilder
  4. JavaFX Tutorial: Basic Layouts
  5. JavaFX Tutorial: Advanced Layouts
  6. JavaFX Tutorial: CSS styling
  7. JavaFX Weaver: Integrating JavaFX and Spring Boot Applications


Anchorpan



AnchorPane is an interesting and powerful layout. This allows you to define anchor points (anchors) to components within the layout. There are 4 types of anchors:





Each component can have any combination of anchors. From zero to all four.



Anchoring a component means that it keeps a certain distance from a certain edge of the layout (for example, TOP). This distance is maintained even when the layout is resized.



For example: anchorRight = 10 means that the component will keep a distance of 10 from the right edge of the layout.



You can specify two anchor points that are not in opposite directions to snap your component to a specific corner of the layout.



The binding TOP = 10 , RIGHT = 10 means that the component will remain in the upper right corner of the layout at a distance of 10 from both edges.







In the above example, the size of each component remains unchanged when the window is resized. However, if you define snap points in opposite directions, you can increase / decrease your component when you resize the window.







You can use various binding combinations, for example:





Defining anchor points in FXML is easy. The following example has all four anchors, but you can only include the ones you want, or not include any.



<AnchorPane> <Button AnchorPane.topAnchor="10" AnchorPane.leftAnchor="10" AnchorPane.rightAnchor="10" AnchorPane.bottomAnchor="10">I am fully anchored!</Button> </AnchorPane>
      
      





Now let's look at how binding is implemented in Java:



 AnchorPane anchorPane = new AnchorPane(); Button button = new Button("I am fully anchored!"); AnchorPane.setTopAnchor(button, 10d); AnchorPane.setBottomAnchor(button, 10d); AnchorPane.setLeftAnchor(button, 10d); AnchorPane.setRightAnchor(button, 10d); anchorPane.getChildren().add(button);
      
      





Gridpan



GridPane is a layout that allows you to arrange your components in a table. Unlike TilePane , which adds components one by one, here, when adding each new component, you need to specify the coordinates of its location in your table.







 <GridPane hgap="10" vgap="10"> <Label GridPane.rowIndex="0" GridPane.columnIndex="0">First</Label> ... </GridPane>
      
      





In Java, when adding a new component, we first specify the ColumnIndex (x) parameter and then RowIndex (y) .



  GridPane grid = new GridPane(); grid.add(new Label("Hello!"), columnIndex, rowIndex);
      
      





Spacing



By default, table cells have no spaces. The components are next to each other, without intervals. The interval can be defined separately for rows and columns, that is, horizontally and vertically.



 <GridPane hgap="10" vgap="10"> ... </GridPane>
      
      





Spacing defined in Java:



 GridPane grid = new GridPane(); grid.setHgap(10); grid.setVgap(10);
      
      





Spacing for multiple cells



Components in a GridPane can span multiple rows and / or columns. The component with rowspan extends to the bottom from its original cell. The colspan component expands to the right.





In Java, there are two ways to set rowSpan and columnSpan. You can install them directly when adding a component to the table:



 grid.add(component, columnIndex, rowIndex, columnSpan, rowSpan);
      
      





Or via GridPane:



 GridPane.setColumnSpan(component, columnSpan); GridPane.setRowSpan(component, rowSpan);
      
      





Sizing



Although in the original example all cells were the same size, this does not have to be so. Table cell sizes are defined as follows:



Column and Row Constraints



As already mentioned, by default, column and row sizes are based on the components inside the panel. Fortunately, it is possible to better control the size of individual columns and rows.



For this, the ColumnContstraints and RowConstraints classes are used.



In fact, you have two options. Either set the percentage of available space for individual rows and columns, or set the preferred width / height. In the latter case, you can also determine the preferred behavior when resizing columns and rows.



Percent



It is pretty simple. You can set the percentage of the available space that will be occupied by a given row or column. When you resize the layout, the rows and columns also change to reflect the new size.



 <GridPane> <columnConstraints> <ColumnConstraints percentWidth="50" /> <ColumnConstraints percentWidth="50" /> </columnConstraints> <rowConstraints> <RowConstraints percentHeight="50" /> <RowConstraints percentHeight="50" /> </rowConstraints> ... </GridPane>
      
      





Same Java example:



 GridPane gridPane = new GridPane(); ColumnConstraints col1 = new ColumnConstraints(); col1.setPercentWidth(50); ColumnConstraints col2 = new ColumnConstraints(); col2.setPercentWidth(50); gridPane.getColumnConstraints().addAll(col1, col2); RowConstraints row1 = new RowConstraints(); row1.setPercentHeight(50); RowConstraints row2 = new RowConstraints(); row2.setPercentHeight(50); gridPane.getRowConstraints().addAll(row1, row2);
      
      





Absolute size



Instead of specifying the size as a percentage, you can determine the preferred and minimum size. In addition, you can specify how the row / column should behave when the layout is resized. Columns use the hgrow property, and rows have the vgrow property.



These properties can have three different meanings.







 <GridPane> <columnConstraints> <ColumnConstraints minWidth="50" prefWidth="100" /> <ColumnConstraints minWidth="50" prefWidth="100" hgrow="SOMETIMES" /> </columnConstraints> <rowConstraints> <RowConstraints minHeight="50" prefHeight="100" /> <RowConstraints minHeight="50" prefHeight="100" vgrow="SOMETIMES" /> </rowConstraints> ... </GridPane>
      
      





Same Java example:



  GridPane gridPane = new GridPane(); ColumnConstraints col1 = new ColumnConstraints(); col1.setMinWidth(50); col1.setPrefWidth(100); ColumnConstraints col2 = new ColumnConstraints(); col2.setMinWidth(50); col2.setPrefWidth(100); col2.setHgrow(Priority.SOMETIMES); gridPane.getColumnConstraints().addAll(col1, col2); RowConstraints row1 = new RowConstraints(); row1.setMinHeight(50); row1.setPrefHeight(100); RowConstraints row2 = new RowConstraints(); row2.setMinHeight(50); row2.setPrefHeight(100); row2.setVgrow(Priority.SOMETIMES); gridPane.getRowConstraints().addAll(row1, row2);
      
      





You can also specify the maxHeight and maxWidth parameters (maximum height and line) for individual rows and columns.



Borderpan



BorderPane is a five-section layout:









You can assign components to individual BorderPane sections:



 <BorderPane> <top> <Label>TOP</Label> </top> <bottom> <Label>BOTTOM</Label> </bottom> <left> <Label>LEFT</Label> </left> <right> <Label>RIGHT</Label> </right> <center> <Label>CENTER</Label> </center> </BorderPane>
      
      





Now the same example in Java:



 Label top = new Label("TOP"); Label bottom = new Label("BOTTOM"); Label left = new Label("LEFT"); Label right = new Label("RIGHT"); Label center = new Label("CENTER"); BorderPane borderPane = new BorderPane(); borderPane.setTop(top); borderPane.setBottom(bottom); borderPane.setLeft(left); borderPane.setRight(right); borderPane.setCenter(center);
      
      





Sizing



All regions, except the central ( center ), have a fixed size. The center then fills the rest of the space.



The upper ( Top ) and lower ( Bottom ) areas stretch across the entire available horizontal space. Their height depends on the height of the component inside.



Left and right fill all available vertical space (except that they occupy the top and bottom). Their width depends on the width of the component inside.



The center is dynamic in size and fills the rest of the space not occupied by other sections. Let's look at an example:







What's next



Now that we know how to use various layouts, we’ll look at how to style JavaFX components with CSS.



All Articles