JavaFX 获取窗格的首选大小

Posted

技术标签:

【中文标题】JavaFX 获取窗格的首选大小【英文标题】:JavaFX Get preferred size of a Pane 【发布时间】:2014-10-24 13:12:33 【问题描述】:

我需要窗格的真正首选大小(来自子项的结果),但我只得到 -1。有没有可能找出来?

好的,这里有一个示例代码: 输出为 -1.0, 0.0, -1.0, -1.0 但显然带有按钮的窗格具有“首选”大小!?只有新线程将窗格的“真实”大小作为输出而不是首选的,因为如果我在 3 秒内调整窗口大小,它会显示“真实”大小而不是开始的首选大小......

public class ButtonTest extends Application

    public static void main(String [] a)
    
        Application.launch(a);
    

    @Override
    public void start(Stage stage) throws Exception
    
        BorderPane root = new BorderPane();

        StackPane pane = new StackPane();


        Button b = new Button("Testbutton");


        pane.getChildren().add(b);
        pane.setStyle("-fx-background-color: red;");

        System.out.println(pane.getPrefWidth());
        System.out.println(pane.getWidth());
        System.out.println(pane.getMinWidth());
        System.out.println(pane.getMaxWidth());

        root.setCenter(pane);
        Scene scene  = new Scene(root);

        Thread t = new Thread(new Runnable()
                   
            @Override
            public void run()
            
                try
                
                    Thread.sleep(3000);
                 catch (InterruptedException e)
                
                    // TODO: Handle Exception
                    e.printStackTrace();
                
                System.out.println(pane.getPrefWidth());
                System.out.println(pane.getWidth());
                System.out.println(pane.getMinWidth());
                System.out.println(pane.getMaxWidth());
            
        );
        t.setDaemon(true);
        t.start();
    

【问题讨论】:

请发布您的代码。顺便说一句,如果您的窗格为空或不可见,或者您没有调用方法 setPreferredSize,您可能会得到这样的结果 preferredsize 到底是什么意思?如果它是-1,则表示任何类约束。如果您想要组件的实际实际大小,请尝试 getBoundsInParent().getWidth() 之类的方法。 【参考方案1】:

默认情况下,StackPane 的 PrefWidth 和 PrefHeight 由父类“Region”中定义的继承约束“USE_COMPUTED_SIZE”(witch 值等于 -1)设置。

这个定义意味着在布局过程中会计算出更合适的尺寸。

也许你的概念放错了地方。 Pref 值用于布局过程,知道它应该如何在画布中排列对象。要了解组件的实际大小,您可以使用我之前提到的 'getBoundsInParent()' 或 'getBoundsInLocal()' (它们之间的区别在 javadoc 中解释)。

但重要的是要理解一个组件只是在布局过程中计算了他的大小。通常,布局过程发生在与事件或 main() 线程不同的线程上。这就是为什么在睡 3 秒后让你成功的原因。您可以尝试使用以下代码让您的代码在 JavaFX GUI 线程中执行(从您的最后一行代码开始):

Platform.runLater(new Runnable() 
    @Override public void run() 
        <Your code in GUI Thread>
    
);

希望能给一点帮助。很抱歉没有为您提供示例代码,但我不在安装环境的机器上。稍后会尝试改进我的答案。

祝你好运。 (请任何人,请随时纠正我的英语,我知道这很糟糕)

【讨论】:

【参考方案2】:

好的,非常感谢您的解释。但是其他方法也不会返回正确的结果...

也许这个案例有助于理解我的目标是什么: 一个相关的问题是我有一个 SplitPane,两部分,现在我隐藏第二部分(分隔符位置 = 1.0)并只显示第一部分,有时我也喜欢显示第二部分。我这样做是为了重新定位分隔线。但是在任何时候都可能发生,第二部分可以用新元素更新(=> 更新必要的大小)。现在,要重新定位分隔线(带有动画),我需要(隐藏的)第二部分的首选大小?!如果没有真正的代码,你知道如何解决这个问题吗?

更新: 我解决了“实际大小”的问题,将公共双重属性添加到窗格并将其绑定到窗格的宽度属性。现在我可以在拆分窗格中为这个双重属性添加一个更改监听器。在第一次可见后,我得到了正确的像素大小。

public DoubleProperty realWidth;

    pane.setPrefWidth(USE_PREF_SIZE);
    pane.setMaxWidth(USE_PREF_SIZE);

    realWidth = new SimpleDoubleProperty(0.0);
    realWidth.bind(this.widthProperty());

=> 从其他地方添加更改侦听器

但是知道我有一个问题,如果我在窗格中添加一个按钮(3 秒后),则不会通知拆分窗格(此 realWidth 属性上的更改侦听器)...

更新:通知 :D 但不是添加按钮而是添加 e。 G。堆栈窗格按预期工作。非常感谢您帮助了解它的工作原理!

【讨论】:

以上是关于JavaFX 获取窗格的首选大小的主要内容,如果未能解决你的问题,请参考以下文章

如何使 JavaFX 窗格适应其内容的大小?

如果节点超出 javafx 的边界,是不是可以自动调整窗格大小

Javafx 网格窗格中心元素

JavaFX:通过窗口大小调整来调整GridPane的大小

JavaFX TextArea - 调整大小时不需要的滚动条

如何使用 JavaFX 垂直堆叠下载窗格?