简体   繁体   English

JavaFX GridPane 设置列/行后节点边界不正确

[英]JavaFX GridPane Incorrect Node Bounds After Setting Column/Row

When setting new row and column positions of a node contained in a GridPane, the bounds do not update until sometime later (My guess is that JavaFX calculates these at the end of the loop).当设置 GridPane 中包含的节点的新行和列位置时,边界直到稍后才会更新(我的猜测是 JavaFX 在循环结束时计算这些)。 I was wondering if there was a way to force these bounds to be re-calculated so that boundsAfter contains the correct values rather than the same as boundsPre (as shown in the output)?.我想知道是否有办法强制重新计算这些边界,以便boundsAfter包含正确的值而不是与boundsPre相同的值(如输出所示)?

Bounds boundsPre = theNode.localToScene(theNode.getBoundsInLocal());
System.out.println("PRE-MOVE: " + boundsPre);

GridPane.setColumnIndex(theNode, newCol);
GridPane.setRowIndex(theNode, newRow);
// Todo: Force JavaFX to recalculate the bounds here

Bounds boundsAfter = theNode.localToScene(theNode.getBoundsInLocal());
System.out.println("BOUNDS: " + boundsAfter );

Output: Output:

PRE-MOVE: BoundingBox [minX:25.0, minY:339.0, minZ:0.0, width:243.0, height:116.0, depth:0.0, maxX:268.0, maxY:455.0, maxZ:0.0]
BOUNDS: BoundingBox [minX:25.0, minY:339.0, minZ:0.0, width:243.0, height:116.0, depth:0.0, maxX:268.0, maxY:455.0, maxZ:0.0]

Solution 1解决方案 1

Call the layout() method on the base pane after setting the row or column position.设置行或列 position 后,在基本窗格上调用layout()方法。 This " Executes a top-down layout pass on the scene graph under this parent " according to the Oracle JavaFX Documentation, which results in the bounds to be re-calculated of all child nodes belonging to the pane.根据 Oracle JavaFX 文档,此“在此父项下的场景图上执行自上而下的布局传递”,这将导致重新计算属于窗格的所有子节点的边界。

Bounds boundsPre = theNode.localToScene(theNode.getBoundsInLocal());
System.out.println("PRE-MOVE: " + boundsPre);

GridPane.setColumnIndex(theNode, newCol);
GridPane.setRowIndex(theNode, newRow);

baseLayout.layout(); // Causes a layout pass which updates the bounds

Bounds boundsAfter = theNode.localToScene(theNode.getBoundsInLocal());
System.out.println("BOUNDS: " + boundsAfter );

Output: Output:

PRE-MOVE: BoundingBox [minX:25.0, minY:87.0, minZ:0.0, width:243.0, height:116.0, depth:0.0, maxX:268.0, maxY:203.0, maxZ:0.0]
BOUNDS: BoundingBox [minX:25.0, minY:213.0, minZ:0.0, width:243.0, height:116.0, depth:0.0, maxX:268.0, maxY:329.0, maxZ:0.0]

Solution 2解决方案 2

If you do not care to update the bounds right away, observe the boundsInLocal property.如果您不想立即更新边界,请观察boundsInLocal属性。 This event will fire when JavaFX completes its next layout pass.当 JavaFX 完成其下一个布局通道时,将触发此事件。

theNode.boundsInLocalProperty().addListener((observableValue, bounds, updatedBounds) ->
{
    System.out.println("BOUNDS: " + updatedBounds);
});

Credit信用

As pointed out by Slaw in the question comments:正如 Slaw 在问题评论中指出的那样:

So either observe the boundsInLocal property and react when it changes, or call applyCss() followed by layout() on the root of the scene.因此,要么观察 boundsInLocal 属性并在它发生变化时做出反应,要么在场景根部调用 applyCss() 后跟 layout()。 The first approach is likely "cleaner"第一种方法可能“更干净”

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM