我已经创建了代码示例:
package stackoverflow;
import javafx.application.Application;
import javafx.geometry.Point2D;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Line;
import javafx.stage.Stage;
public class GetNodeByMousePositionWhileDragged extends Application {
private Line line;
private Group group = new Group();
@Override
public void start(Stage stage) throws Exception {
AnchorPane anchorPane = new AnchorPane();
Circle source = new Circle(30, Color.LIGHTGREEN);
source.setStroke(Color.BLACK);
source.setCenterX(100);
source.setCenterY(100);
source.setOnMousePressed(me -> {
me.consume();
drawLine(source, me);
});
source.setOnMouseDragged(me -> translateLineEnd(getPoint(me)));
source.setOnMouseReleased(event -> group.getChildren().remove(line));
Circle target = new Circle(30, Color.LIGHTBLUE);
target.setStroke(Color.BLACK);
target.setCenterX(400);
target.setCenterY(100);
target.setOnMousePressed(me -> {
me.consume();
drawLine(target, me);
});
target.setOnMouseDragged(me -> translateLineEnd(getPoint(me)));
target.setOnMouseReleased(event -> group.getChildren().remove(line));
group.getChildren().addAll(source, target);
anchorPane.getChildren().addAll(group);
stage.setScene(new Scene(anchorPane, 600, 400));
stage.setMaximized(true);
stage.show();
}
private void drawLine(Circle source, MouseEvent me) {
line = new Line();
line.setStroke(Color.BLACK);
line.setStrokeWidth(1);
line.startXProperty().bind(source.centerXProperty());
line.startYProperty().bind(source.centerYProperty());
translateLineEnd(getPoint(me));
group.getChildren().add(line);
}
private void translateLineEnd(Point2D point) {
line.setEndX(point.getX());
line.setEndY(point.getY());
}
private Point2D getPoint(MouseEvent me) {
return new Point2D(me.getSceneX(), me.getSceneY());
}
}
这里我只是添加两个圆圈,我想通过简单地从一个圆圈拖动到另一个圆圈来用一条线将它们连接起来。但问题是,当我从源圆拖动鼠标时,我想验证鼠标是否进入目标圆。输入时,我只想将线的端点绑定(bind)到目标圆的中心点,或者如果没有输入除源圆之外的任何圆,则在释放鼠标时删除线。
不幸的是,当拖动一个圆圈到另一个圆圈时,没有捕获鼠标事件。但可以获取场景上的鼠标位置。我尝试通过简单地存储所有圆(我有一堆,10K+),每次迭代并检查circle.contains(me.getSceneX(),me.getSceneY())来解决这个问题。在我看来,这有点昂贵,或者就像发明轮子一样。
有一个问题,在 JavaFX 8 中是否可以通过使用内置的 JavaFX 功能以正确的方式根据场景位置获取节点?
最佳答案
您需要稍微修改一下代码:
- 通过在
onDragDetected
事件中调用源节点的startFullDrag
来使用MouseDragEvent
。 - 将该行的
mouseTransparent
设置为true
,以允许 JavaFX 将MouseEvent
传递到target
圆而不是线
。 - 如果鼠标在目标圆圈上释放,请修改事件处理程序以产生不同的结果。
private void drawLine(Circle source, MouseEvent me) {
line = new Line();
line.setMouseTransparent(true);
...
private Group group = new Group();
private boolean removeLine = true;
source.setOnMousePressed(me -> {
me.consume();
drawLine(source, me);
me.setDragDetect(true); // trigger dragDetected event immediately
});
source.setOnDragDetected(evt -> {
source.startFullDrag();
removeLine = true;
});
...
source.setOnMouseReleased(event -> {
if (removeLine) {
group.getChildren().remove(line);
}
});
target.setOnMouseDragReleased(me -> removeLine = false);
关于java - JavaFX 8中如何在鼠标拖动事件位置时获取节点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53589640/