我正在尝试创建UML编辑器。我发现了许多代码变体,这些变体从JavaFX Shape库中提取圆圈,并使其可拖动,并在其中心跟随一行。我以为可以从这些程序中获取逻辑并将其应用于任何类型的窗格(在我的迭代中,我选择了FlowPane)。但是,当我这样做时,生产线只会停留在原位,而不会跟随可拖动的窗格。
我尝试了几次迭代,使用了不同的Pane类型,并尝试使用了Rectangle,但是相同的问题不断发生。矩形图中线的端点不会随之拖动。
(注意:大部分代码来自www.java2s.com上可拖动的圆圈和线条的示例。我的代码由createBox和connectBox函数组成)
我的“创建可拖动矩形”功能:
private FlowPane createBox (double posX, double posY) {
FlowPane node = new FlowPane();
node.setPrefSize(100, 100);
node.setStyle(
"-fx-background-color: black; "
+ "-fx-text-fill: black; "
+ "-fx-border-color: black;");
node.setLayoutX(posX);
node.setLayoutY(posY);
node.setCursor(Cursor.HAND);
node.setOnMousePressed((t) -> {
orgSceneX = t.getSceneX();
orgSceneY = t.getSceneY();
});
node.setOnMouseDragged((t) -> {
double offsetX = t.getSceneX() - orgSceneX;
double offsetY = t.getSceneY() - orgSceneY;
Pane c = (Pane) (t.getSource());
c.setLayoutX(c.getLayoutX() + offsetX);
c.setLayoutY(c.getLayoutY() + offsetY);
orgSceneX = t.getSceneX();
orgSceneY = t.getSceneY();
});
return node;
}
提供的可拖动的圆和直线连接功能:
private Circle createCircle(double x, double y, double r, Color color) {
Circle circle = new Circle(x, y, r, color);
circle.setCursor(Cursor.HAND);
circle.setOnMousePressed((t) -> {
orgSceneX = t.getSceneX();
orgSceneY = t.getSceneY();
Circle c = (Circle) (t.getSource());
c.toFront();
});
circle.setOnMouseDragged((t) -> {
double offsetX = t.getSceneX() - orgSceneX;
double offsetY = t.getSceneY() - orgSceneY;
Circle c = (Circle) (t.getSource());
c.setCenterX(c.getCenterX() + offsetX);
c.setCenterY(c.getCenterY() + offsetY);
orgSceneX = t.getSceneX();
orgSceneY = t.getSceneY();
});
return circle;
}
private Line connect(Circle c1, Circle c2) {
Line line = new Line();
line.startXProperty().bind(c1.centerXProperty());
line.startYProperty().bind(c1.centerYProperty());
line.endXProperty().bind(c2.centerXProperty());
line.endYProperty().bind(c2.centerYProperty());
line.setStrokeWidth(1);
line.setStrokeLineCap(StrokeLineCap.BUTT);
line.getStrokeDashArray().setAll(1.0, 4.0);
return line;
}
我的线连接功能(在我的“矩形”之间一个圆):
private Line connectBox(FlowPane c1, Circle c2) {
Line line = new Line();
line.startXProperty().bind(c1.widthProperty().divide(2).add(c1.getLayoutX()));
line.startYProperty().bind(c1.heightProperty().divide(2).add(c1.getLayoutY()));
line.endXProperty().bind(c2.centerXProperty());
line.endYProperty().bind(c2.centerYProperty());
line.setStrokeWidth(1);
line.setStrokeLineCap(StrokeLineCap.BUTT);
line.getStrokeDashArray().setAll(1.0, 4.0);
return line;
}
程序的开始:
@Override
public void start(Stage primaryStage) {
Group root = new Group();
Scene scene = new Scene(root, 500, 260);
// circles
Circle redCircle = createCircle(100, 50, 30, Color.RED);
Circle blueCircle = createCircle(20, 150, 20, Color.BLUE);
Circle greenCircle = createCircle(40, 100, 40, Color.GREEN);
FlowPane box1 = createBox(100, 130);
Line line1 = connect(redCircle, blueCircle);
Line line2 = connect(redCircle, greenCircle);
Line line3 = connect(greenCircle, blueCircle);
Line line4 = connectBox(box1, blueCircle);
// add the circles
root.getChildren().add(redCircle);
root.getChildren().add(blueCircle);
root.getChildren().add(greenCircle);
root.getChildren().add(box1);
// add the lines
root.getChildren().add(line1);
root.getChildren().add(line2);
root.getChildren().add(line3);
root.getChildren().add(line4);
// bring the circles to the front of the lines
redCircle.toFront();
blueCircle.toFront();
greenCircle.toFront();
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}