JavaFX-将阶段大小绑定到根节点的首选大小 [英] JavaFX - Bind stage size to the root node's preferred size

查看:87
本文介绍了JavaFX-将阶段大小绑定到根节点的首选大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

只要Scene根节点的首选宽度/高度发生变化,我都希望自动调整javafx.stage.Stage的宽度/高度.

I would like to automatically adjust the width/height of a javafx.stage.Stage whenever the preferred width/height of the Scene's root node changes.

这是一个很小的实用程序窗口(用户无法调整大小),其中包含多个javafx.scene.control.TitledPane,并且当其中一个TitledPanes展开时,窗口的高度应增加(否则TitlePane的内容可能超出范围).

It's a small utility window (not resizable by the user) that contains multiple javafx.scene.control.TitledPanes and the window's height should increase when one of these TitledPanes is expanded (otherwise the TitlePane's content may be out of bounds).

不幸的是,我只能找到javafx.stage.Window.sizeToScene(),它最初将窗口的大小设置为根的首选大小.

Unfortunately I could only find javafx.stage.Window.sizeToScene(), which initially sets the window's size to the root's preferred size.

是否可以将舞台大小永久绑定到根节点大小?

Is there a way to permanently bind the Stage size to the root node size?

推荐答案

基于DVarga的示例,我制作了以下解决方案":
InvalidationListener安装在每个子节点的heightProperty上,每个子节点的高度可能会缩小/增长(在此示例中为两个TitlePanes).
heightProperty无效时,将重新计算包含窗口的高度(还改善窗口装饰).

Based on DVarga's example I crafted the following "solution":
A InvalidationListener is installed on the heightProperty of every child node that may shrink/grow in height (two TitlePanes in this example).
When a heightProperty is invalidated, the height of the containing window gets recalculated (also honering window decorations).

示例:

public class SampleApp extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {
        final Label lbl1 = new Label("content");
        final TitledPane tp1 = new TitledPane("First TP", lbl1);

        final Label lbl2 = new Label("more content");
        final TitledPane tp2 = new TitledPane("Second TP", lbl2);

        final VBox rootPane = new VBox(tp1, tp2);

        tp1.heightProperty().addListener((InvalidationListener) observable -> {
            updateWindowHeight(rootPane);
        });

        tp2.heightProperty().addListener((InvalidationListener) observable -> {
            updateWindowHeight(rootPane);
        });

        final Scene scene = new Scene(rootPane);
        primaryStage.setScene(scene);
        primaryStage.sizeToScene();
        primaryStage.setResizable(false);
        primaryStage.show();
    }

    private void updateWindowHeight(final VBox rootPane) {
        final Scene scene = rootPane.getScene();
        if (scene == null) 
            return;
        final Window window = scene.getWindow();
        if (window == null)
            return;
        final double rootPrefHeight = rootPane.prefHeight(-1);
        final double decorationHeight = window.getHeight() - scene.getHeight(); // window decorations
        window.setHeight(rootPrefHeight + decorationHeight);
    }

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

尽管可以按预期工作,但此解决方案仍存在一些主要缺点:

Although it works as intended, there are some major drawbacks with this solution:

  • 您必须在每个可能缩小/增大大小的节点上安装侦听器
  • 从CCD的角度来看这是错误的:子节点不应该负责确定它们所包含的阶段.

我无法获得更清洁的解决方案来工作. javafx.stage.Stagejavafx.scene.Scene太受阻碍(可能的扩展点是最终的或程序包私有的),无法在其所属的位置实现此功能.

I couldn't get a cleaner solution to work. javafx.stage.Stage and javafx.scene.Scene are just too obstructed (possible extension points are final or package-private) to implement this feature where it belongs to.

更新
仅使用window.sizeToScene()而不是

Update
Using just window.sizeToScene() instead of

final double rootPrefHeight = rootNode.prefHeight(-1);
final double decorationHeight = window.getHeight() - scene.getHeight();
window.setHeight(rootPrefHeight + decorationHeight);

调整窗口大小时,产生的口吃"要少得多!

generates a lot less "stutter" when adjusting the window size!

这篇关于JavaFX-将阶段大小绑定到根节点的首选大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆