JavaFX中getWidth()与getLayoutBounds()返回0,如何获取AnchorPane宽度?
解决JavaFX中AnchorPane宽度获取为0的问题
嘿,这个问题我太熟悉了!你遇到的getWidth()返回0的情况,本质是控件还没完成布局渲染就被调用了——JavaFX在控件被添加到场景并完成第一次布局前,不会计算真实的尺寸,所以这时候拿宽度自然是0。下面给你几个实用的解决思路:
1. 用绑定表达式替代固定值获取(最优方案)
你现在直接用anchor_link_label.getWidth()/2是取了一个固定值,但这个值在布局完成前是0,而且后续TextField内容变化时宽度也会变,固定值就失效了。更好的方式是把宽度也做成绑定:
public void bindAnchorPane(DraggableNode source, DraggableNode target){ // 源节点与目标节点的X中点 NumberBinding middleX = Bindings.add( Bindings.divide(source.layoutXProperty(), 2), Bindings.add(Bindings.divide(target.layoutXProperty(), 2), source.getWidth() / 2.0) ); // 源节点与目标节点的Y中点 NumberBinding middleY = Bindings.add( Bindings.divide(source.layoutYProperty(), 2), Bindings.add(Bindings.divide(target.layoutYProperty(), 2), source.getWidth() / 2.0) ); // 用widthProperty()做绑定,自动跟随宽度变化计算居中位置 NumberBinding coordX = Bindings.subtract(middleX, Bindings.divide(anchor_link_label.widthProperty(), 2)); anchor_link_label.layoutXProperty().bind(coordX); anchor_link_label.layoutYProperty().bind(middleY); }
这种方式不仅解决了初始宽度为0的问题,还能在TextField内容变化、宽度改变时自动更新X位置,始终保持居中,完全符合你的需求。
2. 监听布局边界变化
如果一定要手动处理尺寸变化,可以监听控件的layoutBoundsProperty(),等布局完成后再获取真实宽度:
anchor_link_label.layoutBoundsProperty().addListener((observable, oldBounds, newBounds) -> { double realWidth = newBounds.getWidth(); // 这里可以用realWidth重新计算位置 NumberBinding coordX = Bindings.subtract(middleX, realWidth / 2); anchor_link_label.layoutXProperty().bind(coordX); });
不过这种方式不如绑定表达式优雅,毕竟绑定是JavaFX的核心特性,能自动处理所有变化。
3. 延迟获取尺寸(临时方案)
如果只是想在初始阶段获取一次宽度,可以用Platform.runLater()让代码等到JavaFX完成布局后再执行:
Platform.runLater(() -> { double initialWidth = anchor_link_label.getWidth(); // 这里使用initialWidth做初始位置计算 });
但要注意,这种方式只能获取初始宽度,后续TextField宽度变化时不会自动更新,所以只适合一次性场景。
另外,我注意到你代码里有个小语法错误:Bindings.subtract(middleX, anchor_link_label.getWidth()/2;少了一个右括号,记得补上哦!
内容的提问来源于stack exchange,提问作者decman
相关产品推荐
相关产品推荐

