【问题标题】:Sizing a JavaFX stage with a ScrollPane nested in a BorderPane使用嵌套在 BorderPane 中的 ScrollPane 调整 JavaFX 阶段的大小
【发布时间】:2015-12-30 20:12:26
【问题描述】:

在我的应用程序中,我有一个BorderPane,其中包含一个ScrollPane 在中心。 ScrollPane 有两个逻辑部分 topbottom

当我创建一个显示BorderPane 的舞台时,我希望调整舞台的大小,以便仅显示ScrollPanetop 部分,并且用户可以向下滚动以查看bottom 部分,如果他们需要它。

所以我尝试将ScrollPaneprefHeight 属性绑定到top 部分的prefHeight 属性。希望ScrollPane 的高度合适,舞台看起来“恰到好处™”。由于某种原因,这惨遭失败。但是,当我将侦听器附加到 prefHeight 属性时,它确实返回了正确的高度。所以我对发生的事情感到惊讶。

有趣的是,如果我删除 BorderPane 它可以在 SSCCE 中使用,但在实际情况下这不是一个选项。

编辑:SSCCE 更新

这是一个 SSCCE:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Region;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class SSCCE extends Application {

    @Override
    public void start(Stage aStage) throws Exception {
        VBox top = new VBox(new ComboBox<>(), new ComboBox<>(), new ComboBox<>());
        top.setStyle("-fx-background-color: pink");
        top.heightProperty().addListener((aObs, aOld, aNew)->{
            System.out.println(aNew.doubleValue());
        });

        Region regionBottom = new Region();
        regionBottom.setPrefHeight(100);
        regionBottom.setPrefWidth(200);
        regionBottom.setStyle("-fx-background-color: red");

        VBox content = new VBox(top, regionBottom);

        ScrollPane scrollPane = new ScrollPane(content);
        scrollPane.setFitToWidth(true);
        scrollPane.prefHeightProperty().bind(top.prefHeightProperty());

        BorderPane root = new BorderPane(scrollPane);
        root.setTop(new MenuBar(new Menu("Foo")));

        Scene scene = new Scene(root);
        aStage.setScene(scene);
        aStage.sizeToScene();
        aStage.show();
        aStage.toFront();
    }

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

实际结果:

预期结果:

【问题讨论】:

    标签: java layout java-8 javafx-8


    【解决方案1】:

    prefHeightProperty 默认为哨兵值,表示应计算首选项高度。 (Region.USE_COMPUTED_SIZE)。因此,当您绑定滚动窗格的prefHeight 时,您实际上是在指示它执行相同的操作,这基本上意味着它将获得其默认大小。

    说服布局被执行和测量以获得滚动窗格首选高度的正确大小是一个小技巧。正确的布局大小取决于 CSS,因此您必须首先强制应用 CSS,然后您可以请求计算出的顶部区域的 pref 高度。您可以通过调用

    来完成后者
    top.prefHeight(-1);
    

    所以下面的工作:

        ScrollPane scrollPane = new ScrollPane(content);
        scrollPane.setFitToWidth(true);
    //    scrollPane.prefHeightProperty().bind(top.heightProperty());
    
    
        BorderPane root = new BorderPane(scrollPane);
        root.setTop(new MenuBar(new Menu("Foo")));
    
        Scene scene = new Scene(root);
    
        aStage.setScene(scene);
    
        root.applyCss();
        scrollPane.setPrefHeight(top.prefHeight(-1));
        root.requestLayout();
    
        aStage.sizeToScene();
        aStage.show();
        aStage.toFront();
    

    (注意不需要调用aStage.sizeToScene();:无论如何这是默认行为。)

    【讨论】:

    • 有趣,虽然这在 SSCCE 中有效,但在实时应用程序中无效。我猜是因为prefSize 没有在那里手动设置...
    • 正如预期的那样,当 top 的内容没有明确的 prefHeight 设置时,即使绑定 prefHeightProperty 也会失败(因为它是-1)。我有一个改进的 SSCCE,我不确定是否应该更新 OP 或提出新问题?
    • 是的:如果您不设置 prefHeight,它默认为一个标记值 (USE_COMPUTED_SIZE)。更新原来的问题...
    • 感谢您的帮助,尽管您的所有建议都适用于 SSCCE,但我无法让它们在我的现场案例中发挥作用。连同其他出现的问题,我决定采用另一种 UI 设计来避免这个问题。我会接受你的回答,因为它确实解决了 SSCCE。
    • 我想知道标题窗格是否适用于这个用例,顶部区域设置为图形,底部区域设置为滚动窗格,作为内容...
    猜你喜欢
    • 1970-01-01
    • 2014-01-23
    • 2013-07-08
    • 1970-01-01
    • 2017-07-03
    • 2013-06-22
    • 1970-01-01
    • 2016-01-13
    • 1970-01-01
    相关资源
    最近更新 更多