我正在开发一个javaFX项目,我需要对Node的大小进行精确控制。 我的代码当前正确地在需要时更新了prefWidthProperty,并且min和max size设置为使用pref大小,但widthProperty没有更新。
我已经通过将print语句添加为属性的侦听器来验证这一点。 PrefWidthProperty更新,widthProperty没有(直到我点击节点,可能给焦点?)
我尝试在自身及其父级上请求布局,与焦点相同,不起作用。
我目前还不知道如何修复这个非常烦人的bug。看起来目前所有东西总是落后于1布局传递。
用于设置大小和检查更改的代码:
//Set the size
this.setMinSize(Region.USE_PREF_SIZE, Region.USE_PREF_SIZE);
this.setMaxSize(Region.USE_PREF_SIZE, Region.USE_PREF_SIZE);
this.prefWidthProperty().bind(getTotalWidthProperty());
public ObservableValue<? extends Number> getTotalWidthProperty() {
return rightArgument.layoutXProperty().add(rightArgument.translateXProperty()).add(rightArgument.widthProperty()).add(H_GAP);
}
//Check for change:
this.prefWidthProperty().addListener(p -> System.out.println("FB_Pref_"+System.currentTimeMillis() + " " + this.getPrefWidth()));
this.widthProperty().addListener(p -> System.out.println("FB______"+System.currentTimeMillis() + " " + this.getWidth()));
如前所述,FB_Pref按时正确打印,FB_____打印方式太晚。
答案 0 :(得分:1)
如果将min / max设置为pref,则会创建一个固定大小的节点。最小/最大/ pref尺寸将包含在第一个布局阶段。宽度“属性”反映节点上当前设置的宽度。因此,如果您不更改宽度,您的听众将永远不会获得事件。您可以使用getWidth对宽度进行sysout,这总是返回当前宽度。
JavaFX中有两种类型的侦听器,一个changelistener和一个失效侦听器。您添加了一个带有lambdas的失效列表器。这个只在需要时触发,而不是仅在重新布局时进行每次更改。在此处查看更多信息:http://docs.oracle.com/javase/8/javafx/properties-binding-tutorial/binding.htm#sthref12
只需尝试一下:
this.prefWidthProperty().addListener(
(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) -> {
System.out.println("FB_Pref_" + System.currentTimeMillis() + " " + this.getPrefWidth());
});
this.widthProperty().addListener(
(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) -> {
System.out.println("FB______" + System.currentTimeMillis() + " " + this.getWidth())
});
答案 1 :(得分:0)
回答这个问题是一个很长的延迟。当我对 prefWidthProperty 和 prefHeightProperty 执行类似的绑定任务时,我发现了一个解决方案。看起来节点的宽度/高度似乎是首选维度后面的一个布局步骤。执行以下操作将解决此问题(假设此扩展节点):
prefWidthProperty.addListener((observable, oldValue, newValue) -> {
Platform.runLater(() -> getParent().requestLayout());
};
出于某种原因,稍后在Runnable
线程上执行Application
有效。每次设置首选维度时,无论如何都会在MinPrefMaxProperty
类的Region
的 invalidated()方法中调用 requestLayout()。这只会再次强制更新。