JavaFX:绑定到嵌套位置
我有一个包含一些vbox和行的窗格。我想将线的端点绑定到VBox中的锚,基本上我想绑定到嵌套在VBox中任意深度的节点的位置,但我无法确定哪个值表示相对于顶部窗格的节点位置。我尝试过布局属性、转换属性以及本地的边界和父级的边界,但它们似乎都不起作用。我错过了什么 如果需要的话,我可以提供一个代码示例,但我认为这无助于更好地解释我的问题,因为我无法让它工作 编辑:我忘了提到VBox可以在窗格中自由移动,这就是我需要绑定行的原因 编辑:这里有一些资料显示了我的进展。我可以找到正确的位置,但没有约束力JavaFX:绑定到嵌套位置,javafx,binding,position,Javafx,Binding,Position,我有一个包含一些vbox和行的窗格。我想将线的端点绑定到VBox中的锚,基本上我想绑定到嵌套在VBox中任意深度的节点的位置,但我无法确定哪个值表示相对于顶部窗格的节点位置。我尝试过布局属性、转换属性以及本地的边界和父级的边界,但它们似乎都不起作用。我错过了什么 如果需要的话,我可以提供一个代码示例,但我认为这无助于更好地解释我的问题,因为我无法让它工作 编辑:我忘了提到VBox可以在窗格中自由移动,这就是我需要绑定行的原因 编辑:这里有一些资料显示了我的进展。我可以找到正确的位置,但没有约束力
public class Graph extends Application {
private double startX;
private double startY;
private ObjectBinding<Bounds> bounds;
private DoubleBinding tx;
private DoubleBinding ty;
@Override
public void start(Stage primaryStage) throws Exception {
Pane pane = new Pane();
Circle target = new Circle(5, Color.RED);
VBox node = wrap(target);
Line connector = new Line();
bounds = Bindings.createObjectBinding(() -> {
Bounds nodeLocal = target.getBoundsInLocal();
Bounds nodeScene = target.localToScene(nodeLocal);
Bounds nodePane = pane.sceneToLocal(nodeScene);
return nodePane;
},
target.boundsInLocalProperty(),
target.localToSceneTransformProperty(),
pane.localToSceneTransformProperty()
);
connector.setStartX(0);
connector.setStartY(0);
tx = Bindings.createDoubleBinding(() -> bounds.get().getMinX(), bounds);
ty = Bindings.createDoubleBinding(() -> bounds.get().getMinY(), bounds);
connector.endXProperty().bind(tx);
connector.endYProperty().bind(ty);
connector.setStroke(Color.BLACK);
pane.getChildren().add(node);
pane.getChildren().add(connector);
node.relocate(100, 100);
primaryStage.setScene(new Scene(pane, 300, 300));
primaryStage.show();
}
private VBox wrap(Circle target) {
VBox node = new VBox(new Label("Node"), new StackPane(new Rectangle(50, 50, Color.GRAY), target));
node.setOnMousePressed(event -> {
Node source = (Node) event.getSource();
startX = source.getBoundsInParent().getMinX() - event.getScreenX();
startY = source.getBoundsInParent().getMinY() - event.getScreenY();
});
node.setOnMouseDragged(event -> {
Node source = (Node) event.getSource();
double offsetX = event.getScreenX() + startX;
double offsetY = event.getScreenY() + startY;
source.relocate(offsetX, offsetY);
});
return node;
}
}
假设任何节点都有一个父节点或间接祖先窗格,基本思想是
ObjectBinding<Bounds> boundsInPaneBinding = Bindings.createObjectBinding(() -> {
Bounds nodeLocal = node.getBoundsInLocal();
Bounds nodeScene = node.localToScene(nodeLocal);
Bounds nodePane = pane.sceneToLocal(nodeScene);
return nodePane ;
}, node.boundsInLocalProperty(), node.localToSceneTransformProperty(),
pane.localToSceneTransformProperty());
这里棘手的部分是确保绑定不会过早地被垃圾收集。请参阅以进行讨论。首先,需要保留对绑定的引用:
private ObjectBinding<Bounds> boundsInPaneBinding ;
它几乎满足了我的需求。排队的人都在正确的地方,但他们没有被束缚住。不过我想我知道问题出在哪里,没关系。它不起作用。我试图绑定到VBox中某个节点的位置,而不是VBox本身。@RuckusT Boom您可以使用完全相同的技术,只需将VBox替换为上面代码中感兴趣的节点即可。对答案进行编辑以反映这一点。它们不保持绑定的问题可能是:只需确保保留对绑定的引用。这对我来说仍然不起作用。“让我把它弄得乱七八糟,看看我能不能弄明白。”RuckusT Boom更新了答案。出于我不太清楚的原因,您需要评估LocalToScenetTransformProperty,以便获得要启动的绑定。
private ObjectBinding<Bounds> boundsInPaneBinding ;
boundsInPaneBinding = Bindings.createObjectBinding(() -> {
Bounds nodeLocal = node.getBoundsInLocal();
// note how this actually gets the value of localToSceneTransformProperty():
Bounds nodeScene = node.getLocalToSceneTransform().apply(nodeLocal);
Bounds nodePane = pane.sceneToLocal(nodeScene);
return nodePane ;
}, node.boundsInLocalProperty(), node.localToSceneTransformProperty(),
pane.localToSceneTransformProperty());