我试图写出关于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));
所以我无法理解我应该如何编写规则以便将行放在它的位置?谢谢。
答案 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);
}
}