我试图创建一个属性来识别我何时将一条线从一个节点拖到另一个节点。
但是,其他节点似乎无法识别它何时被悬停。
以下是我用来拖动鼠标时执行操作的代码:
nfaNode.setOnMouseDragged(event1 -> {
nfaNode.setDelete(false);
final Point2D mouseInParent = nfaNode.localToParent(event1.getX(), event1.getY());
if (event1.isShiftDown()) {
nfaNode.getArrow().setVisible(true);
nfaNode.setArrowBounds(nfaNode.getBubble().getCenterX(), nfaNode.getBubble().getCenterY(),
event1.getX(), event1.getY());
nfaNodes.stream().filter(n -> n.isHover() && !n.equals(nfaNode)).forEach(n -> System.out.println("Hovering over " + n.getText().getText()));
return;
}
nfaNode.getArrow().setVisible(false);
nfaNode.setLayoutX(mouseInParent.getX() + dragDelta.getDragDeltaX());
nfaNode.setLayoutY(mouseInParent.getY() + dragDelta.getDragDeltaY());
});
当我从Q_0拖到Q_1时,有没有理由说Q_1为什么不能识别我的鼠标?
答案 0 :(得分:0)
问题是,isHover
确实会返回false,因为MOUSE_ENTERED
事件未被Node
触发(仅针对Node
isHover()
你开始拖拽了。)
来自Node
的文件:
请注意,当前实现的悬停依赖于鼠标输入和 退出事件以确定此节点是否处于悬停状态;
为了理解发生了什么,我在这里复制MouseEvent
documentation的一部分(重点是我的):
有三种类型的拖动手势。它们都是由 鼠标按下事件并因鼠标释放而终止 event,源节点决定将进行哪种手势。
简单的按下 - 拖动 - 释放手势是默认。它是最好习惯的 允许更改形状的大小,拖动它等等。的全 按下拖动释放手势被传递到一个节点。当鼠标按钮时 按下,选择最顶部的节点和所有后续鼠标 事件被传递到同一节点,直到释放按钮。如果 从这些事件生成鼠标单击事件,它仍然是 传递到同一节点。
在简单的按下 - 拖动 - 释放手势期间,其他节点不是 参与并没有得到任何活动。如果需要涉及这些节点 在手势中,必须激活完整的按下 - 拖动 - 释放手势。 此手势最适合用于通过" wires"连接节点,拖动 节点到其他节点等。更详细地描述了这种手势类型 在MouseDragEvent中,它包含传递给手势的事件 目标
所以,你的"拖动"在我的第一句话中是拖动文档中的第一种不能与其他Node
一起使用的内容,因此鼠标输入事件不会被用于isHover
的{{1}}用于Circle
方法计算。
在您的情况下,您需要第二种类型的拖动,因此您必须在节点之间实现拖动机制。一个非常好的起点是official tutorial。
这是一个用public class Main extends Application {
@Override
public void start(Stage primaryStage) {
try {
BorderPane root = new BorderPane();
Scene scene = new Scene(root, 400, 400);
List<NFANode> nfaNodes = new LinkedList<>();
Pane pane = new Pane();
root.setCenter(pane);
// On pane click we add circles
pane.setOnMouseClicked(event -> {
if (event.getButton().equals(MouseButton.PRIMARY)) {
// If any of the nodes are in hover, do not add new circle
if (nfaNodes.stream().anyMatch(n -> n.getCircle().isHover()))
return;
// Create and initialize the circle, add it to the pane
// Wrap it in a NFANode and add it to the list
Circle circle = new Circle();
NFANode nfaNode = new NFANode(circle);
nfaNodes.add(nfaNode);
pane.getChildren().add(circle);
circle.setCenterX(event.getX());
circle.setCenterY(event.getY());
circle.setRadius(20);
// Circle started to be dragged
circle.setOnDragDetected(ev -> {
System.out
.println("Drag detected on circle: " + circle.getBoundsInParent());
// The content will be linked
Dragboard db = circle.startDragAndDrop(TransferMode.LINK);
// Add the index of the NFANode to the DragBoard
ClipboardContent content = new ClipboardContent();
content.putString(new Integer(nfaNodes.indexOf(nfaNode)).toString());
db.setContent(content);
});
// A circle is hovered while in a drag
circle.setOnDragOver(e -> {
// Only accept different nodes than the source
if (e.getGestureSource() != circle) {
String content = e.getDragboard().getContent(DataFormat.PLAIN_TEXT).toString();
Circle draggedCircle = nfaNodes.get(Integer.parseInt(content)).getCircle();
System.out.println("Drag over circle: " + circle.getBoundsInParent());
System.out.println("Circle dragged: " + draggedCircle.getBoundsInParent());
e.acceptTransferModes(TransferMode.ANY);
}
event.consume();
});
// Drag finished on a node
circle.setOnDragDropped(e -> {
String content = e.getDragboard().getContent(DataFormat.PLAIN_TEXT).toString();
Circle draggedCircle = nfaNodes.get(Integer.parseInt(content)).getCircle();
System.out.println("Drag completed over circle: " + circle.getBoundsInParent());
System.out.println("Circle dragged: " + draggedCircle.getBoundsInParent());
e.acceptTransferModes(TransferMode.ANY);
});
}
});
primaryStage.setScene(scene);
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
public class NFANode {
private Circle circle;
public NFANode(Circle circle) {
this.circle = circle;
}
public Circle getCircle() {
return circle;
}
public void setCircle(Circle circle) {
this.circle = circle;
}
}
public static void main(String[] args) {
launch(args);
}
}
s实现DnD的SSCCE(无线图)
Drag detected on circle: BoundingBox [minX:73.0, minY:97.0, minZ:0.0, width:40.0, height:40.0, depth:0.0, maxX:113.0, maxY:137.0, maxZ:0.0]
Drag over circle: BoundingBox [minX:275.0, minY:289.0, minZ:0.0, width:40.0, height:40.0, depth:0.0, maxX:315.0, maxY:329.0, maxZ:0.0]
Circle dragged: BoundingBox [minX:73.0, minY:97.0, minZ:0.0, width:40.0, height:40.0, depth:0.0, maxX:113.0, maxY:137.0, maxZ:0.0]
Drag completed over circle: BoundingBox [minX:275.0, minY:289.0, minZ:0.0, width:40.0, height:40.0, depth:0.0, maxX:315.0, maxY:329.0, maxZ:0.0]
Circle dragged: BoundingBox [minX:73.0, minY:97.0, minZ:0.0, width:40.0, height:40.0, depth:0.0, maxX:113.0, maxY:137.0, maxZ:0.0]
和示例输出:
{{1}}