gpt4 book ai didi

javafx - JavaFX如何绘制箭头? ( Pane )

转载 作者:行者123 更新时间:2023-12-02 11:51:53 25 4
gpt4 key购买 nike

我需要从无向图制作有向图。我可以画线-边,但我不知道如何制作箭头:

public class Edge extends Group {

protected Cell source;
protected Cell target;

Line line;

public Edge(Cell source, Cell target) {

this.source = source;
this.target = target;

source.addCellChild(target);
target.addCellParent(source);

line = new Line();

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));

getChildren().addAll(line);
}

最佳答案

您需要再添加 2 条线来制作箭头(或使用具有相同点的多边形来制作填充箭头)。

请注意,箭头的方向可以根据“主”连接的线端开始和结束之间的差异来确定。构成箭头的每条线的一端需要与主线的一端处于相同的坐标。另一端可以通过将主线方向的部分和与主线正交的部分组合起来计算:

public class Arrow extends Group {

private final Line line;

public Arrow() {
this(new Line(), new Line(), new Line());
}

private static final double arrowLength = 20;
private static final double arrowWidth = 7;

private Arrow(Line line, Line arrow1, Line arrow2) {
super(line, arrow1, arrow2);
this.line = line;
InvalidationListener updater = o -> {
double ex = getEndX();
double ey = getEndY();
double sx = getStartX();
double sy = getStartY();

arrow1.setEndX(ex);
arrow1.setEndY(ey);
arrow2.setEndX(ex);
arrow2.setEndY(ey);

if (ex == sx && ey == sy) {
// arrow parts of length 0
arrow1.setStartX(ex);
arrow1.setStartY(ey);
arrow2.setStartX(ex);
arrow2.setStartY(ey);
} else {
double factor = arrowLength / Math.hypot(sx-ex, sy-ey);
double factorO = arrowWidth / Math.hypot(sx-ex, sy-ey);

// part in direction of main line
double dx = (sx - ex) * factor;
double dy = (sy - ey) * factor;

// part ortogonal to main line
double ox = (sx - ex) * factorO;
double oy = (sy - ey) * factorO;

arrow1.setStartX(ex + dx - oy);
arrow1.setStartY(ey + dy + ox);
arrow2.setStartX(ex + dx + oy);
arrow2.setStartY(ey + dy - ox);
}
};

// add updater to properties
startXProperty().addListener(updater);
startYProperty().addListener(updater);
endXProperty().addListener(updater);
endYProperty().addListener(updater);
updater.invalidated(null);
}

// start/end properties

public final void setStartX(double value) {
line.setStartX(value);
}

public final double getStartX() {
return line.getStartX();
}

public final DoubleProperty startXProperty() {
return line.startXProperty();
}

public final void setStartY(double value) {
line.setStartY(value);
}

public final double getStartY() {
return line.getStartY();
}

public final DoubleProperty startYProperty() {
return line.startYProperty();
}

public final void setEndX(double value) {
line.setEndX(value);
}

public final double getEndX() {
return line.getEndX();
}

public final DoubleProperty endXProperty() {
return line.endXProperty();
}

public final void setEndY(double value) {
line.setEndY(value);
}

public final double getEndY() {
return line.getEndY();
}

public final DoubleProperty endYProperty() {
return line.endYProperty();
}

}

使用

@Override
public void start(Stage primaryStage) {
Pane root = new Pane();
Arrow arrow = new Arrow();
root.getChildren().add(arrow);

root.setOnMouseClicked(evt -> {
switch (evt.getButton()) {
case PRIMARY:
// set pos of end with arrow head
arrow.setEndX(evt.getX());
arrow.setEndY(evt.getY());
break;
case SECONDARY:
// set pos of end without arrow head
arrow.setStartX(evt.getX());
arrow.setStartY(evt.getY());
break;
}
});

Scene scene = new Scene(root, 400, 400);

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

关于javafx - JavaFX如何绘制箭头? ( Pane ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41353685/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com