Search code examples
javafxlayout

JavaFX BorderPane Bottom is clipped by Center


I have a BorderPane with stuff in the center and in the bottom parts. My problem is that when I shrink the window vertically, the center part clips over the bottom part.

Here's an example: https://o7planning.org/en/10629/cache/images/i/2768251.gif
(source: o7planning.org)

When the window is resized vertically, the bottom button "disappears". I would like for the bottom part to always be displayed at the same size (ie. minimum size given by its content), while the center can be shrunk as much as necessary.

As a consequence, the window should have a minimal height which is the height of the bottom part (which should never be hidden).

Here is the code from the example:

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
 
public class BorderPaneDemo extends Application {
 
    @Override
    public void start(Stage primaryStage) throws Exception {
        BorderPane root = new BorderPane();
   
        root.setPadding(new Insets(15, 20, 10, 10));
   
        // TOP
        Button btnTop = new Button("Top");
        btnTop.setPadding(new Insets(10, 10, 10, 10));
        root.setTop(btnTop);
        // Set margin for top area.
        BorderPane.setMargin(btnTop, new Insets(10, 10, 10, 10));
        
   
        // LEFT
        Button btnLeft = new Button("Left");
        btnLeft.setPadding(new Insets(5, 5, 5, 5));
        root.setLeft(btnLeft);
        // Set margin for left area.
        BorderPane.setMargin(btnLeft, new Insets(10, 10, 10, 10));
   
        // CENTER
        Button btnCenter = new Button("Center");
        btnCenter.setPadding(new Insets(5, 5, 5, 5));
        root.setCenter(btnCenter);
         // Alignment.
         BorderPane.setAlignment(btnCenter, Pos.BOTTOM_CENTER);
   
        // RIGHT
        Button btnRight = new Button("Right");
        btnRight.setPadding(new Insets(5, 5, 5, 5));
        root.setRight(btnRight);
        // Set margin for right area.
        BorderPane.setMargin(btnRight, new Insets(10, 10, 10, 10));
   
        // BOTTOM
        Button btnBottom = new Button("Bottom");
        btnBottom.setPadding(new Insets(5, 5, 5, 5));
        root.setBottom(btnBottom);
        // Alignment.
        BorderPane.setAlignment(btnBottom, Pos.TOP_RIGHT);
   
        // Set margin for bottom area.
        BorderPane.setMargin(btnBottom, new Insets(10, 10, 10, 10));
   
        Scene scene = new Scene(root, 550, 250);
   
        primaryStage.setTitle("BorderPane Layout Demo");
        primaryStage.setScene(scene);
        primaryStage.show();
    }
   
    public static void main(String[] args) {
      launch(args);
    }
 
}

Solution

  • I was not able to achieve this using BorderPane. I thought that setting the BorderPane's top and center Nodes min-height to zero would achieve this. I was able to achieve this with an HBox as the root and VBox holding middle Nodes.

    I then set the min-height on the Top's root Node and the Center's root Node.

    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.scene.control.Button;
    import javafx.scene.layout.HBox;
    import javafx.scene.layout.Priority;
    import javafx.scene.layout.VBox;
    import javafx.stage.Stage;
    
    public class BorderPaneDemo extends Application {
    
        @Override
        public void start(Stage primaryStage) throws Exception {
    
            Button btnTop = new Button("Top");
            Button btnLeft = new Button("Left");
            Button btnCenter = new Button("Center");
            Button btnRight = new Button("Right");
            Button btnBottom = new Button("Botton");
    
    
            VBox vbCenter = new VBox(btnTop, btnCenter, btnBottom);
            HBox root = new HBox(btnLeft, vbCenter, btnRight);
    
            HBox.setHgrow(vbCenter, Priority.ALWAYS);
            VBox.setVgrow(btnCenter, Priority.ALWAYS);
    
            btnTop.setMaxWidth(Double.MAX_VALUE);
            btnCenter.setMaxWidth(Double.MAX_VALUE);
            btnBottom.setMaxWidth(Double.MAX_VALUE);
    
            btnLeft.setMaxHeight(Double.MAX_VALUE);
            btnCenter.setMaxHeight(Double.MAX_VALUE);
            btnRight.setMaxHeight(Double.MAX_VALUE);
    
            //The Top and Center root node needs to have a min height of zero
            btnTop.setMinHeight(0);
            btnCenter.setMinHeight(0);
    
            Scene scene = new Scene(root, 550, 250);
    
            primaryStage.setTitle("BorderPane Layout Demo");
            primaryStage.setScene(scene);
            primaryStage.show();
        }
    
        public static void main(String[] args) {
          launch(args);
        }
    
    }
    

    enter image description here