【发布时间】:2021-06-16 00:56:11
【问题描述】:
如果按钮被动态添加到布局中,getWidth 属性会加回 0;但是,可以立即达到首选尺寸。我假设这是因为系统没有机会计算按钮的大小(因为它是刚刚添加的)。
最小可重现示例:
import javafx.application.Application;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class AgentApp extends Application {
public static void main(String[] args){
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
Stage tagTest = new Stage();
VBox topBox = new VBox();
Parent tagRoot = topBox;
Button btn = new Button("Add a Button dynamically");
btn.setOnAction(event -> {
Button dBtn = new Button("How big is this?!");
dBtn.setOnAction(event1 -> System.out.println("Width is actually: " + dBtn.getWidth())); /* (1) */
topBox.getChildren().add(dBtn);
System.out.println("Width:" + dBtn.getWidth()); /* (2) */
});
topBox.getChildren().add(btn);
Scene tagsScene = new Scene(tagRoot,400,200);
tagTest.setScene(tagsScene);
tagTest.show();
}
}
(1) 处的按钮宽度打印正确,而(2) 处的宽度打印出 0.0。这是出乎意料的。
在节点的父节点 (topbox) 上调用 layout 函数不会产生任何结果;既不继承也不调用自定义容器中的受保护函数layoutChildren。
但我认为大小本身必须在某处计算,因为大小是在按下dBtn 时计算的。那时如何强制计算大小?
更新:
异步请求宽度返回正确的大小:
Button dBtn = new Button("How big is this?!");
dBtn.setOnAction(event1 -> System.out.println("Width is actually: " + dBtn.getWidth()));
topBox.getChildren().add(dBtn);
Platform.runLater(() -> System.out.println("btn width: " + btn.getWidth()));
但由于这是在未指定时间运行的异步调用,因此大小仍然无法立即获得。
【问题讨论】:
-
不太明白你想要的是什么:实际尺寸只有在展示后才可用(你可能在展示后打印输出时看到)
-
在用户界面不是静态的,而是动态生成的情况下:一些UI相关的计算需要新添加按钮的大小。
-
如果将打印语句移到
tagTest.show();之后会发生什么 -
“用空格扩展文本”是什么意思?这听起来像是您正在寻找比您需要的更多的手动布局。也许提供minimal reproducible example 会让您的目标和问题更加明显。
-
大小通常在调用其父节点的
layoutChildren()方法时分配给节点。所以获得正确大小的可靠方法是对窗格进行子类化,覆盖layoutChildren(),调用super.layoutChildren(),然后查询节点的大小。一般layoutChildren()方法是应该进行布局计算的地方。对于几乎所有用例,您都可以使用现有的布局窗格来管理布局,而不是自己定义。
标签: user-interface javafx