Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/flutter/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaFX:绑定到嵌套位置_Javafx_Binding_Position - Fatal编程技术网

JavaFX:绑定到嵌套位置

JavaFX:绑定到嵌套位置,javafx,binding,position,Javafx,Binding,Position,我有一个包含一些vbox和行的窗格。我想将线的端点绑定到VBox中的锚,基本上我想绑定到嵌套在VBox中任意深度的节点的位置,但我无法确定哪个值表示相对于顶部窗格的节点位置。我尝试过布局属性、转换属性以及本地的边界和父级的边界,但它们似乎都不起作用。我错过了什么 如果需要的话,我可以提供一个代码示例,但我认为这无助于更好地解释我的问题,因为我无法让它工作 编辑:我忘了提到VBox可以在窗格中自由移动,这就是我需要绑定行的原因 编辑:这里有一些资料显示了我的进展。我可以找到正确的位置,但没有约束力

我有一个包含一些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());