JavaFX setPrefSize is not changing vBox size

mxignas :

I am very beginner at JavaFX and im facing this issue: I want to make layout like this: What i need

And this is what i have: enter image description here

It seems that i tried a lot of different layouts and i just cant get it right. I ended up with VBox'es and thats the best i can get. Even though I described "vBox2" size with "PrefSize" to be Half Half of the whole scene, it doesnt react at all.

This is my code:

    @Override // Override the start method in the Application class
    public void start(Stage primaryStage) {

        // Create a border pane
        BorderPane pane = new BorderPane();

         // Place nodes in the pane
        pane.setLeft(getVBox());
        pane.setBottom(getVBox2());
        pane.setRight(getVBox3());

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

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

        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);
        }
        vBox.setStyle("-fx-border-style: solid inside;");
        vBox.setPrefSize(500, 400);

        return vBox;
    }

    private VBox getVBox2() {
        VBox vBox2 = new VBox(15);
        vBox2.setPadding(new Insets(15, 5, 5, 5));
        vBox2.getChildren().add(new Label("Vbox2"));

        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(5, 5, 5, 15));
            vBox2.getChildren().add(course);
        }
        vBox2.setStyle("-fx-border-style: solid inside;");
        vBox2.setPrefSize(500, 400);

        return vBox2;
    }

    private VBox getVBox3() {
        VBox vBox3 = new VBox(15);
        vBox3.setPadding(new Insets(15, 5, 5, 5));
        vBox3.getChildren().add(new Label("vbox3"));

        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));
            vBox3.getChildren().add(course);
        }
        vBox3.setStyle("-fx-border-style: solid inside;");
        vBox3.setPrefSize(500, 800);

        return vBox3;
    }

}

I cant use FXML or style it in CSS.

Thank you for any advices.

James_D :

The general process for a layout pane (such as VBox or BorderPane) to layout its child nodes is as follows:

  1. Query the child nodes for their minimum, maximum, and preferred sizes
  2. Compute the position and size to be allocated to each child node, adhering to its own layout policy, and making a best effort to respect the minimum, preferred, and maximum sizes of the child nodes

  3. Request the child nodes perform their own layout, allocating the sizes calculated to each

It's not always possible to respect all the min/max/pref constraints of the child nodes; e.g. if the sum of the minimum heights of all children of a VBox is greater than the height of the VBox itself, there's simply no way to fit all the children in the layout. Conversely, if the height of the VBox is greater than the sum of all the preferred heights of the children, there will be extra vertical space to be allocated somehow. Most layout panes have settings that configure how to handle these situations: some of these settings apply to the entire layout pane, others are applied on a per-child basis.

The layout policy for a BorderPane is essentially as follows:

  • The top and bottom nodes are allocated the full width of the BorderPane, and each get their preferred height. These nodes are positioned across the full width of the border pane, at the top and bottom respectively. This is the part that makes the BorderPane behave differently to the way you require.
  • The left and right nodes are allocated the full height of the BorderPane, less the height of the top and bottom nodes, and each get their preferred width. These are positioned at the left and right of the border pane, respectively, below the top and above the bottom nodes.
  • The center node receives all the remaining space.

This is adjusted if the resulting sizes violate minimum or maximum sizes of the nodes, if possible.

So the layout in your image is exactly as expected; vbox2 gets the full width and its preferred height; vbox gets its preferred width and the remaining height of the border pane, and vbox3 gets the remaining space.

You can basically achieve what you're looking for here by placing vbox and vbox2 in a VBox of their own, and placing that VBox in the left of the border pane; then placing vbox3 in the center (the right would work too):

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.VBox;
import javafx.stage.Stage;

public class Layout extends Application {
    @Override // Override the start method in the Application class
    public void start(Stage primaryStage) {

        // Create a border pane
        BorderPane pane = new BorderPane();

         // Place nodes in the pane

        VBox left = new VBox(getVBox(), getVBox2());
        pane.setLeft(left);
        pane.setCenter(getVBox3());

        // 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 VBox getVBox() {
        VBox vBox = new VBox(15);
        vBox.setPadding(new Insets(15, 5, 5, 5));
        vBox.getChildren().add(new Label("vbox"));

        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);
        }
        vBox.setStyle("-fx-border-style: solid inside;");
        vBox.setPrefSize(500, 400);

        return vBox;
    }

    private VBox getVBox2() {
        VBox vBox2 = new VBox(15);
        vBox2.setPadding(new Insets(15, 5, 5, 5));
        vBox2.getChildren().add(new Label("Vbox2"));

        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(5, 5, 5, 15));
            vBox2.getChildren().add(course);
        }
        vBox2.setStyle("-fx-border-style: solid inside;");
        vBox2.setPrefSize(500, 400);

        return vBox2;
    }

    private VBox getVBox3() {
        VBox vBox3 = new VBox(15);
        vBox3.setPadding(new Insets(15, 5, 5, 5));
        vBox3.getChildren().add(new Label("vbox3"));

        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));
            vBox3.getChildren().add(course);
        }
        vBox3.setStyle("-fx-border-style: solid inside;");
        vBox3.setPrefSize(500, 800);

        return vBox3;
    }

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

}

You haven't specified how you want this to behave on resizing the window, but the "center" region will essentially be more "responsive" than the left.

The initial window looks like:

enter image description here

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=169457&siteId=1