JavaFX 根据 VBox 元素的数量动态调整窗口大小

问题描述 投票:0回答:1

我想构建一个实用工具,当从

VBox
添加/删除子项时,它可以垂直调整大小。子项通过用户输入进行修改。用户无法调整应用程序窗口的大小。

我创建了以下 FXML 文件:

<AnchorPane fx:id="rootPane" 
            maxHeight="-Infinity" maxWidth="-Infinity" 
            minHeight="-Infinity" minWidth="-Infinity" 
            prefHeight="400.0" prefWidth="600.0" 
            xmlns="http://javafx.com/javafx/17.0.2-ea" 
            xmlns:fx="http://javafx.com/fxml/1" 
            fx:controller="myProject.controller.DynamicResizeController">
    <children>
        <VBox fx:id="vBox" 
              layoutX="148.0" layoutY="144.0" 
              prefHeight="200.0" prefWidth="200.0">
            <children>
                <Label text="This is a label" />
                <Button fx:id="addButton" 
                        onAction="#handleAddButtonClick" text="Add Element" />
                <Button fx:id="removeButton" 
                        text="Remove Element" />
            </children>
        </VBox>
    </children>
</AnchorPane>

和一个控制器类:

public class DynamicResizeController {

    @FXML
    private VBox vBox;

    @FXML
    private AnchorPane rootPane;

    public void handleAddButtonClick(ActionEvent event) {
        Label label = new Label("New Element added!");
        vBox.getChildren().add(label);
        calculateAndResize();
    }

    private void calculateAndResize() {
        double totalHeight = 0;
        for (Node child : vBox.getChildren()) {
            totalHeight += child.prefHeight(-1) + child.getLayoutY();
        }

        resizeStage(totalHeight);
    }

    private void resizeStage(double height) {
        // set height of stage to height
    }

}

主要课程非常基础:

public class DynamicResizeApplication extends Application {

    @Override
    public void start(Stage stage) throws Exception {
        FXMLLoader fxmlLoader = new FXMLLoader(DynamicResizeApplication.class.getResource("view/dynamic-resize-view.fxml"));
        Scene scene = new Scene(fxmlLoader.load());

        stage.setScene(scene);
        stage.initStyle(StageStyle.UNDECORATED);
        stage.show();
    }

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

}

如何设置舞台高度?我没有找到在控制器类中访问它的方法。

java javafx resize vbox
1个回答
0
投票

+1 对于@jewelsea 的建议。事实上你需要使用

sizeToScene()
方法让计算自动完成并调整窗口大小。

话虽如此,调用

sizeToScene()
并不总是能让你的窗口压缩到其内容宽度。您需要考虑有关
sizeToScene()
工作原理的一些其他因素。

主要是任何 prefWidth/prefHeight 设置都会影响 sizeToScene() 计算。除此之外,最小/最大设置也发挥了作用。

所以我的建议是:

  • 您需要遍历场景中的所有节点,以查看您需要的首选项/最小/最大设置。如果不需要,请删除任何 min/max/pref 声明。
  • 我知道,如果您从 SceneBuilder 生成 fxml,您将获得为您生成的所有属性。 不要爱上他们!。检查 FXML 中的每个属性,如果您确实不需要它(或不知道它),请将其删除。如果它没有按预期工作,那么您就会知道要考虑哪些属性。 (这就是你将学习的方式)

所以回到你的问题:我不确定你为什么考虑 AnchorPane,但 pref/min/max 的所有设置都不是必需的。因此,即使您使用

sizeToScene()
,您的窗口也不会调整大小。

下面是删除所有尺寸设置然后调用 sizeToScene() 后的 fxml 的演示和代码:

<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Button?>
<AnchorPane fx:id="rootPane" xmlns="http://javafx.com/javafx/17.0.2-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="myProject.controller.DynamicResizeController">
    <children>
        <VBox fx:id="vBox" layoutX="148.0" layoutY="144.0" >
            <children>
                <Label text="This is a label" />
                <Button fx:id="addButton" onAction="#handleAddButtonClick" text="Add Element" />
                <Button fx:id="removeButton" text="Remove Element" />
            </children>
        </VBox>
    </children>
</AnchorPane>

您的控制器代码:

public void handleAddButtonClick(ActionEvent event) {
  Label label = new Label("New Element added!");
  vBox.getChildren().add(label);
  vBox.getScene().getWindow().sizeToScene();
}
© www.soinside.com 2019 - 2024. All rights reserved.