【发布时间】:2021-06-17 04:34:01
【问题描述】:
我是 JavaFX 的完全新手,对 Java 整体来说还是个新手。我正在设计用于自学项目的无向图的图形表示。现在,我正在尝试使节点可拖动,以便边缘将拉伸以保持与节点的连接。在 2 个节点连接的情况下,我已经实现了这一点。但是,添加三分之一会有些奇怪。
假设我们有这种情况:
Cell testOne = new Cell ("testOne", 123);
Cell testTwo = new Cell ("testTwo", 456);
Cell testThree = new Cell ("testThree", 200);
testOne.addConnection(testTwo);
testOne.addConnection(testThree);
我得到的是三个节点,它们的一般区域随机散布着两条线(值得注意的是,这些节点的位置非常随机)。如果我在 testTwo 或 testThree 周围移动,单线将折衷连接到 testOne。无论如何,第二行保持不变。我不得不认为,不知何故,正在发生的事情是其中一个 EventHandler 正在从它们各自的单元中“拔出”,或者以某种方式其中一条线在内存中丢失了。这是画线的代码(我知道它真的很笨重)。此方法在 Graph 类中,它控制类的图形(oop)表示。 “cells”是存储其所有节点的 ArrayList,“connections”是 Cell 实例中的 arrayList,用于跟踪它所连接的所有节点,“LinesBetween”是一个 HashMap,Cell 实例跟踪一条线是否已经在两个节点之间绘制。
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();
}
});
}
}
}
}
}
}
【问题讨论】:
-
我发布了我可以对问题代码所在位置做出的最准确的猜测。
-
这并不意味着它是minimal reproducible example(←阅读链接的帮助页面了解更多信息)。
-
另外,与其尝试在事件处理程序中移动边缘,不如将它们绑定到适当的节点位置可能更容易。然后,当您移动节点时,正确的边会自动更新。
-
谢谢,我正在考虑为绑定创建属性,但是当我看到 setEndX/Y 方法时,我认为我已经作弊了。然后我是否必须调用 relocate() 或其他东西才能在显示屏上更新?抱歉,StackOverFlow 的礼仪很差,显然还在学习。