2016-12-27 22 views
2

無向グラフから有向グラフを作成する必要があります。私はラインエッジを描くことができますが、私は矢を作る方法がわからない:矢印を描く方法JavaFX? (ペイン)

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

答えて

6

あなたが満たされた矢先に同じポイントで矢印ヘッド(またはPolygonを作るために2つの以上の行を追加する必要があります)。

「矢印」の方向は、「メイン」接続の行末の開始と終了の差に基づいて決定できます。矢頭を構成する各線の一端は、幹線の端と同じ座標にある必要があります。他端は、メインラインの方向の一部とメインラインにortogonal部分を組み合わせることによって計算することができる。

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(); 
} 
関連する問題