【问题标题】:How to draw arrow JavaFX? (pane)如何绘制箭头JavaFX? (窗格)
【发布时间】:2016-12-27 23:58:25
【问题描述】:

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

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

【问题讨论】:

    标签: javafx graph pane


    【解决方案1】:

    您需要再添加 2 行来制作箭头(或 Polygon 与填充箭头的相同点)。

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-26
      • 2015-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多