如何在JavaFX中的面板中连接两个圆圈?

时间:2019-02-21 20:48:49

标签: javafx

我想知道是否有人可以给我提示,以连接两个分别位于单独的窗格中的节点。我正在做一个创造性的编程项目,目标是视觉上展示图形算法。到目前为止,这是我的进步。这是图片以及正在发生的事情的描述:

通过双击创建两个CircleNode(CircleNodes是扩展组的类。它们由Circle和添加到窗格中的标签组成)A和B

enter image description here

使用源代码在A上开始一条完整的拖动线。拖动的线只是用户的视觉效果

enter image description here

通过在B上释放并创建两个从A到B以及B到A的LinkNode来结束拖动

enter image description here

从A到B创建一个LinkNode(只是一个扩展组并包含line和distance()函数的类),以便节点可以链接在一起。

问题是,当通过在窗格中获取Circle的centerX和centerY创建LinkNode时,LinkNode中的线与预期位置不同。我相当确定问题是无法在窗格中获取圆坐标。

CircleNode(DraggedLine通常无关紧要,但可能会引起问题):

    class CircleNode extends Pane {
    //Node will have fixed height and width
    private final static int R = 20;
    //Node will have a name so that it can be found
    private String name;
    private DraggedLine draggedLine;
    private double x, y;
    private Circle circle;
    private Pane layout;
    //collection of colors which the circle can be
    CircleNode(double x, double y, String name){
        layout = new StackPane();
        Color[] colors = {Color.BLUE, Color.GRAY, Color.YELLOW, Color.GREEN, Color.VIOLET};
        int randColorIndex = (int)(Math.random() * colors.length);
        Label label = new Label(name);
        this.name = name;
        circle = new Circle(R);
        circle.setFill(colors[randColorIndex]);
        circle.setStrokeWidth(2);
        circle.setStroke(Color.BLACK);
        setTranslateX(x);
        setTranslateY(y);
        //lost on what to do here
        //layout.setTranslateX(x);
        //layout.setTranslateY(y);
        //circle.setCenterX(x);
        //circle.setCenterY(y);
        //circle.setLayoutX(x);
        //circle.setLayoutY(y);
        this.createLinkHandler();
        layout.getChildren().addAll(circle, label);
        getChildren().add(layout);
        display();
    }

    private void createLinkHandler(){
        this.setOnDragDetected(de -> {
            this.startFullDrag();
            System.out.println("Full drag started on " + ((CircleNode)de.getSource()).getName());
            //System.out.println("Drag detected and Full drag started");
            //Line line = drawLine(de.get)
            //LinkNode temp_link = new LinkNode(this.getTranslateX(), this.getTranslateY(), de.getX(), de.getY()) );
        });
        this.setOnMouseDragged(de -> {
            this.getChildren().remove(draggedLine);
            draggedLine = new DraggedLine(circle.getLayoutX(), circle.getLayoutY(), de.getX(), de.getY());
            this.getChildren().add(draggedLine);
        });
        this.setOnMouseDragReleased(de -> {
            this.getChildren().remove(draggedLine);
            CircleNode source = (CircleNode)de.getGestureSource();
            if(de.getGestureSource() == null){
                System.out.println("Failed to create link\nNo CircleNode found to complete the drag");
                return;
            }
            System.out.println("Drag started on " + source.getName() + " and ended on: " + this.name);
            this.getChildren().add(new LinkNode(source, this));
            source.getChildren().add(new LinkNode(this, source));

            this.getChildren().remove(draggedLine);
        });        
    }

    public void display(){
        System.out.println("Layout x, y: " + layout.getTranslateX() + ", " + layout.getTranslateY() );
        System.out.println("Circle x, y:  " + circle.getCenterX() + ", " + circle.getCenterY());
        System.out.println("Translate x, y: " + getTranslateX() + ", " + getTranslateY());
    }

    public String getName(){ return name; }

    public Circle getCircle(){ return circle;}

    public Pane getLayout(){ return layout;}

    public void removeDraggedLine(){if(draggedLine != null) getChildren().remove(draggedLine);}

    private static Line drawLine(double x1, double y1, double x2, double y2){
        return new Line(x1, y1, x2, y2);
    }


    }

    class DraggedLine extends Group{
    private Line line;

    DraggedLine(double x1, double y1, double x2, double y2){
        drawLine(x1, y1, x2, y2);
        getChildren().add(line);
    }

    public void drawLine(double x1, double y1, double x2, double y2){
        this.line = new Line(x1, y1, x2, y2);
    }

    }

LinkNode:

    class LinkNode extends Group {
    private double distance;
    private CircleNode start, end;
    private Line line;

    LinkNode(CircleNode start, CircleNode end){
        if(start.getName().equals(end.getName())){
            System.out.println("You can't connect a circle node to itself");
            return;
        }
        this.start = start;
        this.end = end;
        //this is part causing problems:
        //Circle c1 = start.getCircle(), c2 = end.getCircle();
        //double x1 = c1.getCenterX(), y1= c1.getCenterY(), x2 = c2.getCenterX(), y2 = c2.getCenterY();
        //double x1 = c1.getCenterX(), y1= c1.getCenterY(), x2 = c2.getCenterX(), y2 = c2.getCenterY();
        double x1 = start.getTranslateX(), y1= start.getTranslateY(), x2 = end.getTranslateX(), y2= start.getTranslateY();
        distance = distance(x1, y1, x2, y2);
        line = new Line(x1, y1, x2, y2);
        line.setStroke(Color.MIDNIGHTBLUE);
        line.setStrokeWidth(3);
        getChildren().add(line);
        System.out.println(toString());
        System.out.println("Coordinate start: " + x1 + ", " + y1 +"\nCoordinate end: " + x2 + ", " + y2);
        start.removeDraggedLine();
        end.removeDraggedLine();
    }

    public String toString(){ return start.getName() + "->" + end.getName() + "\nDistance: " + distance;}

    private static double distance(double x1, double y1, double x2,double  y2){
        return Math.sqrt( Math.pow((x1 - x2), 2) + Math.pow((y1 - y2), 2));
    }

    public double getDistance(){
        return distance;
    }

    public Line getLine(){
        return line;
    }

    public CircleNode getStart(){
        return start;
    }

    public CircleNode getEnd(){
        return end;
    }
}

编辑: 我能够通过完全避免使用窗格来解决此问题,但是这样我无法显示Node的名称。新图片:

Create two Nodes, A and B with their names unable to be displayed because they are in a group Start a drag on one and release a Drag on the other to create a link between the two Do the same thing with another node

class CircleNode extends Group{
    private String name;
    private double x, y;
    private Circle circle;
    private Line draggedLine;
    private Pane layout;
    private static final int R = 15;

    public CircleNode(double x, double y, String name){
        //layout = new Pane();
        //layout.getChildren().add(label);
        this.name = name;
        circle = new Circle(x, y, R);
        Label label = new Label(name, circle);
        this.x = x;
        this.y = y;
        circle.setFill(selectColor());
        circle.setStrokeWidth(2);
        circle.setStroke(Color.BLACK);
        this.createLinkHandler();
        getChildren().addAll(circle);
    }

    private void createLinkHandler(){
        this.setOnDragDetected(de -> {
            this.startFullDrag();
           // draggedLine = new Line(x, y, de.getX(), de.getY());
            System.out.println("Full drag started on " + ((CircleNode)de.getSource()).name);
            //System.out.println("Drag detected and Full drag started");
            //Line line = drawLine(de.get)
            //LinkNode temp_link = new LinkNode(this.getTranslateX(), this.getTranslateY(), de.getX(), de.getY()) );
        });

        this.setOnMouseDragged(de -> {
            //getChildren().remove(draggedLine);
            //draggedLine = new Line(x, y, de.getX(), de.getY());
            //getChildren().add(draggedLine);
        });

        this.setOnMouseDragReleased(de -> {
            System.out.println("Full drag ended on: " + this.name);
            //getChildren().remove(draggedLine);
            CircleNode source = (CircleNode)de.getGestureSource();
            if(de.getGestureSource() == null){
                System.out.println("Failed to create link, No CircleNode found to complete the drag");
                return;
            }
            //System.out.println("Drag started on " + source.name + " and ended on: " + this.name);
            this.getChildren().add(new LinkNode(source, this));
            source.getChildren().add(new LinkNode(this, source));
        });
    }

    public Color selectColor(){
        Color[] colors = {Color.VIOLET, Color.GREEN, Color.GRAY, Color.GOLD, Color.BLUE, Color.BLUEVIOLET, Color.YELLOW};
        return colors[(int)(Math.random() * (colors.length - 1 - 1) + 1)];
    }

    public Circle getCircle(){
        return circle;
    }
}

class LinkNode extends Group{
    private Line line;
    private CircleNode start, end;
    private double distance;
    public LinkNode(CircleNode start, CircleNode end){
        this.start = start;
        this.end = end;
        double x1 = start.getCircle().getCenterX(), y1 = start.getCircle().getCenterY(), x2 = end.getCircle().getCenterX(),
                y2 = end.getCircle().getCenterY();
        line = new Line(x1, y1, x2, y2);
        this.distance = distance(x1, y1, x2, y2);
        getChildren().add(line);
    }

    public static double distance(double x1, double y1, double x2, double y2){
        return Math.sqrt( Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2) );
    }
}

0 个答案:

没有答案