我想知道是否有人可以给我提示,以连接两个分别位于单独的窗格中的节点。我正在做一个创造性的编程项目,目标是视觉上展示图形算法。到目前为止,这是我的进步。这是图片以及正在发生的事情的描述:
通过双击创建两个CircleNode(CircleNodes是扩展组的类。它们由Circle和添加到窗格中的标签组成)A和B
使用源代码在A上开始一条完整的拖动线。拖动的线只是用户的视觉效果
通过在B上释放并创建两个从A到B以及B到A的LinkNode来结束拖动
从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) );
}
}