使用边缘JavaFX连接两个节点

时间:2016-02-24 06:56:42

标签: javafx drawing line coordinates nodes

我试图写出关于connecting nodes with edge的正确规则。我使用了stackoverflow中使用来自两个可连接nodes的数据的解决方案:

        line.startXProperty().bind( source.layoutXProperty().add(source.getBoundsInParent().getWidth() / 2.0));
        line.startYProperty().bind( source.layoutYProperty().add(source.getBoundsInParent().getHeight() / 2.0));

        line.endXProperty().bind( target.layoutXProperty().add( target.getBoundsInParent().getWidth() / 2.0));
        line.endYProperty().bind( target.layoutYProperty().add( target.getBoundsInParent().getHeight() / 2.0));

但它并没有奏效。它绘制下一行: enter image description here

所以我无法理解我应该如何编写规则以便将行放在它的位置?谢谢。

1 个答案:

答案 0 :(得分:1)

尝试

line.startXProperty().bind(Bindings.createDoubleBinding(() -> {
    Bounds b = source.getBoundsInParent();
    return b.getMinX() + b.getWidth() / 2 ;
}, source.boundsInParentProperty());
line.startYProperty().bind(Bindings.createDoubleBinding(() -> {
    Bounds b = source.getBoundsInParent() ;
    return b.getMinY() + b.getHeight() / 2 ;
}, source.boundsInParentProperty());

并且类似于目标和行尾。问题下面的评论基本上解释了这是如何工作的:你需要一些可观察的东西,它取决于父母的界限并计算中心。

SSCCE(点击添加一个圆圈,再次点击添加一个连接的圆圈,拖动圆圈以查看效果):

import java.util.Random;

import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.event.Event;
import javafx.geometry.Bounds;
import javafx.geometry.Point2D;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Line;
import javafx.stage.Stage;

public class DraggingConnectedNodes extends Application {

    private final Random rng = new Random();

    @Override
    public void start(Stage primaryStage) {
        Pane pane = new Pane();
        ObjectProperty<Node> lastUnconnectedNode = new SimpleObjectProperty<>();
        pane.setOnMouseClicked(e -> {
            Circle c = createDraggingCircle(e.getX(), e.getY(), 25, pane, randomColor());
            pane.getChildren().add(c);
            if (lastUnconnectedNode.get() == null) {
                lastUnconnectedNode.set(c);
            } else {
                connect(lastUnconnectedNode.get(), c);
                lastUnconnectedNode.set(null);
            }

        });

        Scene scene = new Scene(pane, 600, 600);

        primaryStage.setScene(scene);
        primaryStage.show();

    }

    private void connect(Node n1, Node n2) {
        if (n1.getParent() != n2.getParent()) {
            throw new IllegalArgumentException("Nodes are in different containers");
        }
        Pane parent = (Pane) n1.getParent();
        Line line = new Line();
        line.startXProperty().bind(Bindings.createDoubleBinding(() -> {
            Bounds b = n1.getBoundsInParent();
            return b.getMinX() + b.getWidth() / 2 ;
        }, n1.boundsInParentProperty()));
        line.startYProperty().bind(Bindings.createDoubleBinding(() -> {
            Bounds b = n1.getBoundsInParent();
            return b.getMinY() + b.getHeight() / 2 ;
        }, n1.boundsInParentProperty()));
        line.endXProperty().bind(Bindings.createDoubleBinding(() -> {
            Bounds b = n2.getBoundsInParent();
            return b.getMinX() + b.getWidth() / 2 ;
        }, n2.boundsInParentProperty()));
        line.endYProperty().bind(Bindings.createDoubleBinding(() -> {
            Bounds b = n2.getBoundsInParent();
            return b.getMinY() + b.getHeight() / 2 ;
        }, n2.boundsInParentProperty()));
        parent.getChildren().add(line);
    }

    private Circle createDraggingCircle(double radius, double x, double y, Pane parent, Color fill) {
        Circle c = new Circle(radius, x, y, fill);
        ObjectProperty<Point2D> mouseLoc = new SimpleObjectProperty<>();
        c.setOnMousePressed(e -> mouseLoc.set(new Point2D(e.getX(), e.getY())));
        c.setOnMouseDragged(e -> {
            double deltaX = e.getX() - mouseLoc.get().getX();
            double deltaY = e.getY() - mouseLoc.get().getY();
            c.setCenterX(c.getCenterX() + deltaX);
            c.setCenterY(c.getCenterY() + deltaY);
            mouseLoc.set(new Point2D(e.getX(), e.getY()));
        });
        c.addEventFilter(MouseEvent.MOUSE_CLICKED, Event::consume);
        return c ;
    }

    private Color randomColor() {
        return new Color(rng.nextDouble(), rng.nextDouble(), rng.nextDouble(), 1);
    }

    public static void main(String[] args) {
        launch(args);
    }
}