I'm a complete novice to JavaFX, and fairly new to Java overall. I'm designing a graphical representation of an undirected graph for use in a self-teaching project. Right now, I'm trying to make nodes draggable such that the edges will stretch to stay connected with their nodes. I have achieved that in the case of 2 nodes with a connection. However, adding a third does something weird.
Say we have this situation:
Cell testOne = new Cell ("testOne", 123);
Cell testTwo = new Cell ("testTwo", 456);
Cell testThree = new Cell ("testThree", 200);
testOne.addConnection(testTwo);
testOne.addConnection(testThree);
What I get is three nodes with two lines strewn randomly in their general area (worth noting the nodes are positioned in a crudely random way). If I move around testTwo or testThree, a single line will trade off being connected to testOne. The second line remains unchanged no matter what. I have to think that somehow what's happening is that one of the EventHandlers is getting "unplugged" from their respective cells, or else somehow one of the lines is getting lost in memory. Here's the code to draw lines (I know it's really clunky). This method is in the Graph class, which controls graphic (oop) representation of the class. "cells" is the ArrayList storing all its nodes, "connections" is the arrayList in the Cell instance that keeps track of all the nodes it's connected to, and "LinesBetween" is a HashMap the Cell instance keeping track of whether a line has already been drawn between the two nodes.
public void drawAndManageEdgeLines(){
if (cells.size() > 1) { //don't wanna make connections if there's only one cell, or none
int count = 0;
for (Cell cell : cells) { // for every cell on the graph
List<Cell> connectionsList = cell.getConnections(); // look at that cell's connections
if (!connectionsList.isEmpty()) {// validate that the cell is actually supposed to be connected to something
for (Cell connection : connectionsList) { // go through all their connections
if (!cell.getLinesBetween().get(connection) && cell.getLinesBetween().get(connection) != null) { //check to see whether there is already a line between them
Circle sourceCircle = cell.getCellView();
Circle targetCircle = connection.getCellView();
Bounds sourceBound = sourceCircle.localToScene(sourceCircle.getBoundsInLocal());
Bounds targetBound = targetCircle.localToScene(targetCircle.getBoundsInLocal());
double targetX = targetBound.getCenterX();
double targetY = targetBound.getCenterY();
double sourceX = sourceBound.getCenterX();
double sourceY = sourceBound.getCenterY();
edge = new Line(sourceX, sourceY, targetX, targetY);
edge.setStroke(Color.BLACK);
edge.setStrokeWidth(2);
getChildren().add(edge);
edge.toBack();
cell.setLinesBetweenEntry(connection, true);
connection.setLinesBetweenEntry(cell, true);
// these handlers control where the line is dragged to
cell.addEventHandler(MouseEvent.MOUSE_DRAGGED, new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent e) {
edge.setStartX(e.getSceneX()); //this is a really cool method
edge.setStartY(e.getSceneY());
e.consume();
}
});
System.out.println("on round " + count + " we got there: ");
connection.addEventHandler(MouseEvent.MOUSE_DRAGGED, new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent e) {
edge.setEndX(e.getSceneX());
edge.setEndY(e.getSceneY());
e.consume();
}
});
}
}
}
}
}
}