JavaFX setPrefSize 没有改变 vBox 的大小

JavaFX setPrefSize is not changing vBox size

我是 JavaFX 的新手,我正面临这个问题: 我想这样布局:What i need

这就是我所拥有的:enter image description here

看来我尝试了很多不同的布局,但我就是做不好。我最终得到了 VBox'es,那是我能得到的最好的。尽管我将 "vBox2" 大小和 "PrefSize" 描述为整个场景的一半,但它根本没有反应。

这是我的代码:

    @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;
    }

}

我无法在 CSS 中使用 FXML 或设置样式。

感谢您的任何建议。

我能想到的解决问题的最简单方法是构建两个 HBox 并将 VBox 放在其中。 举个例子:Sebastian Damm 创造了这个简单的: https://www.javacodegeeks.com/2012/07/javafx-20-layout-panes-hbox-and-vbox.html

    import javafx.application.Application;
    import javafx.geometry.Pos;
    import javafx.scene.Scene;
    import javafx.scene.control.Button;
    import javafx.scene.layout.HBox;
    import javafx.scene.layout.VBox;
    import javafx.stage.Stage;


/**
 *
 * Created on: 20.03.2012
 * @author Sebastian Damm
 */
public class HBoxandVBoxExample extends Application
{
    @Override
    public void start(Stage primaryStage) throws Exception
    {                
        HBox hbox = new HBox(50);
        hbox.setAlignment(Pos.CENTER); // default TOP_LEFT

        VBox vbox1 = new VBox();
        vbox1.setAlignment(Pos.BOTTOM_CENTER);
        vbox1.setStyle("-fx-border-style: solid;"
                + "-fx-border-width: 1;"
                + "-fx-border-color: black");

        VBox vbox2 = new VBox(10);
        vbox2.setAlignment(Pos.CENTER);
        vbox2.setStyle("-fx-border-style: solid;"
                + "-fx-border-width: 1;"
                + "-fx-border-color: black");

        VBox vbox3 = new VBox(20);
        vbox3.setAlignment(Pos.TOP_CENTER);
        vbox3.setStyle("-fx-border-style: solid;"
                + "-fx-border-width: 1;"
                + "-fx-border-color: black");

        for (int i = 0; i < 5; i++)
        {
            Button bt = new Button("Button " + (i+1));
            Button bt2 = new Button("Button " + (i+1)); // unfortunately there´s no "clone" or "copy" method
            Button bt3 = new Button("Button " + (i+1));

            vbox1.getChildren().add(bt);
            vbox2.getChildren().add(bt2);
            vbox3.getChildren().add(bt3);
        }

        hbox.getChildren().addAll(vbox1, vbox2, vbox3);
        Scene scene = new Scene(hbox, 350, 250); // the hbox is the root node

        primaryStage.setTitle("HBox and VBox Example");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

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

布局窗格(例如VBoxBorderPane)布局其child节点的一般过程如下:

  1. 查询 child 个节点的最小值、最大值和首选 尺码
  2. 计算分配给每个的位置和大小child 节点,坚持自己的布局策略,并尽最大努力 遵守 child 节点

  3. 的最小、首选和最大大小
  4. 请求child节点执行自己的布局,分配 尺寸计算到每个

并不总是能够遵守 child 节点的所有 min/max/pref 约束;例如如果一个VBox的所有children的最小高度之和大于VBox本身的高度,根本就没有办法容纳所有的children在布局中。相反,如果 VBox 的高度大于 children 的所有首选高度的总和,则会有额外的垂直 space 以某种方式分配。大多数布局窗格都有配置如何处理这些情况的设置:其中一些设置适用于整个布局窗格,其他设置在 per-child 基础上应用。

BorderPane 的布局策略基本上如下:

  • topbottom 节点分配了 BorderPane 的整个宽度,并且每个节点都获得了它们的首选高度。这些节点位于边框窗格的整个宽度上,分别位于顶部和底部。 这是使 BorderPane 的行为与您要求的方式不同的部分。
  • leftright 节点分配了 BorderPane 的全高,减去 topbottom 节点的高度,并且每个人都有自己喜欢的宽度。它们位于边框窗格的左侧和右侧,分别位于 top 节点下方和 bottom 节点上方。
  • center节点接收所有剩余的space。

如果可能的话,如果生成的大小违反节点的最小或最大大小,则会对此进行调整。

所以您图片中的布局完全符合预期; vbox2 获取全宽及其首选高度; vbox 获取其首选宽度和边框窗格的剩余高度,vbox3 获取剩余的 space。

通过将 vboxvbox2 放在它们自己的 VBox 中,然后将 VBox 放在边框窗格的左侧;然后将 vbox3 放在中间(右边也可以):

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); }

}

您还没有指定在调整 window 大小时您希望它如何表现,但是 "center" 区域基本上会比左边 "responsive" 大。

最初的 window 看起来像: