JavaFX区分拖动和点击
JavaFX distinguish Drag and Click
我正在尝试在 JavaFX 中执行以下操作。我正在使用 Canvas 在屏幕上绘制内容,我希望发生以下情况:
当我点击 Canvas 表面时(如快速按下和释放):发生了一些事情
当我在 Canvas 表面上拖动时(例如按下并移动,然后松开):会发生其他情况
但是我希望它在我拖动时排除点击动作,所以如果我拖动,我点击时不应该发生的事情。可悲的是,似乎当我释放鼠标时,释放和单击事件都会启动,即使我拖动也是如此。
方法isStillSincePress()
can be used together with the getEventType()
,均来自MouseEvent
API.
也许您需要在 MOUSE_PRESSED
和 MOUSE_RELEASED
之间实现鼠标移动的阈值以提高可用性。
@wcomnisky
非常感谢您的帮助。我最后做了什么(我尝试在释放事件处理程序中使用 isStillSincePress() 并且它似乎仍在将短距离拖动视为点击......虽然我可能做错了什么)是这样的:在我记录的鼠标按下处理程序中按下坐标(也许这个想法类似于 isStillSincePressed() 方法。它的名称/描述可能已经暗示了它)pressX = event.getX(); pressY = event.getY()
并且在鼠标释放处理程序中我这样做:if( (pressX == event.getX() ) && (pressY == event.getY()) ) doClickAction(); else doDragEndAction()
。似乎可以工作.. 在拖动时处理动作,我会尝试使用通常的拖动处理程序。
有点晚了,万一有人来这里寻求解决方案呢。我创建了一个简单的 class 来处理它。
用法:
clickNotDragDetectingOn(yourNode)
.withPressedDurationTreshold(150)
.setOnMouseClickedNotDragged((mouseEvent) -> {
// logic here
});
代码:
class MouseClickNotDragDetector {
private final Node node;
private Consumer<MouseEvent> onClickedNotDragged;
private boolean wasDragged;
private long timePressed;
private long timeReleased;
private long pressedDurationTreshold;
private MouseClickNotDragDetector(Node node) {
this.node = node;
node.addEventHandler(MOUSE_PRESSED, (mouseEvent) -> {
this.timePressed = currentTimeMillis();
});
node.addEventHandler(MOUSE_DRAGGED, (mouseEvent) -> {
this.wasDragged = true;
});
node.addEventHandler(MOUSE_RELEASED, (mouseEvent) -> {
this.timeReleased = currentTimeMillis();
this.fireEventIfWasClickedNotDragged(mouseEvent);
this.clear();
});
this.pressedDurationTreshold = 200;
}
static MouseClickNotDragDetector clickNotDragDetectingOn(Node node) {
return new MouseClickNotDragDetector(node);
}
MouseClickNotDragDetector withPressedDurationTreshold(long durationTreshold) {
this.pressedDurationTreshold = durationTreshold;
return this;
}
MouseClickNotDragDetector setOnMouseClickedNotDragged(Consumer<MouseEvent> onClickedNotDragged) {
this.onClickedNotDragged = onClickedNotDragged;
return this;
}
private void clear() {
this.wasDragged = false;
this.timePressed = 0;
this.timeReleased = 0;
}
private void fireEventIfWasClickedNotDragged(MouseEvent mouseEvent) {
if ( this.wasDragged ) {
debug("[CLICK-NOT-DRAG] dragged!");
return;
}
if ( this.mousePressedDuration() > this.pressedDurationTreshold ) {
debug("[CLICK-NOT-DRAG] pressed too long, not a click!");
return;
}
debug("[CLICK-NOT-DRAG] click!");
this.onClickedNotDragged.accept(mouseEvent);
}
private long mousePressedDuration() {
return this.timeReleased - this.timePressed;
}
}
我正在尝试在 JavaFX 中执行以下操作。我正在使用 Canvas 在屏幕上绘制内容,我希望发生以下情况:
当我点击 Canvas 表面时(如快速按下和释放):发生了一些事情
当我在 Canvas 表面上拖动时(例如按下并移动,然后松开):会发生其他情况
但是我希望它在我拖动时排除点击动作,所以如果我拖动,我点击时不应该发生的事情。可悲的是,似乎当我释放鼠标时,释放和单击事件都会启动,即使我拖动也是如此。
方法isStillSincePress()
can be used together with the getEventType()
,均来自MouseEvent
API.
也许您需要在 MOUSE_PRESSED
和 MOUSE_RELEASED
之间实现鼠标移动的阈值以提高可用性。
@wcomnisky
非常感谢您的帮助。我最后做了什么(我尝试在释放事件处理程序中使用 isStillSincePress() 并且它似乎仍在将短距离拖动视为点击......虽然我可能做错了什么)是这样的:在我记录的鼠标按下处理程序中按下坐标(也许这个想法类似于 isStillSincePressed() 方法。它的名称/描述可能已经暗示了它)pressX = event.getX(); pressY = event.getY()
并且在鼠标释放处理程序中我这样做:if( (pressX == event.getX() ) && (pressY == event.getY()) ) doClickAction(); else doDragEndAction()
。似乎可以工作.. 在拖动时处理动作,我会尝试使用通常的拖动处理程序。
有点晚了,万一有人来这里寻求解决方案呢。我创建了一个简单的 class 来处理它。
用法:
clickNotDragDetectingOn(yourNode)
.withPressedDurationTreshold(150)
.setOnMouseClickedNotDragged((mouseEvent) -> {
// logic here
});
代码:
class MouseClickNotDragDetector {
private final Node node;
private Consumer<MouseEvent> onClickedNotDragged;
private boolean wasDragged;
private long timePressed;
private long timeReleased;
private long pressedDurationTreshold;
private MouseClickNotDragDetector(Node node) {
this.node = node;
node.addEventHandler(MOUSE_PRESSED, (mouseEvent) -> {
this.timePressed = currentTimeMillis();
});
node.addEventHandler(MOUSE_DRAGGED, (mouseEvent) -> {
this.wasDragged = true;
});
node.addEventHandler(MOUSE_RELEASED, (mouseEvent) -> {
this.timeReleased = currentTimeMillis();
this.fireEventIfWasClickedNotDragged(mouseEvent);
this.clear();
});
this.pressedDurationTreshold = 200;
}
static MouseClickNotDragDetector clickNotDragDetectingOn(Node node) {
return new MouseClickNotDragDetector(node);
}
MouseClickNotDragDetector withPressedDurationTreshold(long durationTreshold) {
this.pressedDurationTreshold = durationTreshold;
return this;
}
MouseClickNotDragDetector setOnMouseClickedNotDragged(Consumer<MouseEvent> onClickedNotDragged) {
this.onClickedNotDragged = onClickedNotDragged;
return this;
}
private void clear() {
this.wasDragged = false;
this.timePressed = 0;
this.timeReleased = 0;
}
private void fireEventIfWasClickedNotDragged(MouseEvent mouseEvent) {
if ( this.wasDragged ) {
debug("[CLICK-NOT-DRAG] dragged!");
return;
}
if ( this.mousePressedDuration() > this.pressedDurationTreshold ) {
debug("[CLICK-NOT-DRAG] pressed too long, not a click!");
return;
}
debug("[CLICK-NOT-DRAG] click!");
this.onClickedNotDragged.accept(mouseEvent);
}
private long mousePressedDuration() {
return this.timeReleased - this.timePressed;
}
}