JavaFX-将阶段大小绑定到根节点的首选大小 [英] JavaFX - Bind stage size to the root node's preferred size
问题描述
只要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.TitledPane
s 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.Stage
和javafx.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屋!