JavaFX区分拖动和单击

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaFX区分拖动和单击相关的知识,希望对你有一定的参考价值。

我正在尝试在JavaFX中执行以下操作。我正在使用Canvas在屏幕上绘制内容,我希望发生以下情况:

当我点击画布表面(如快速按下和释放)时:会发生一些事情

当我在Canvas表面上拖动时(如按下并移动,然后释放):ELSE发生了什么

如果我拖动,我希望它排除点击操作,所以如果我拖动,如果我点击不会发生什么会发生。可悲的是,似乎当我发布鼠标时,即使我拖动,也会发布释放和点击事件。

答案

这有点晚了,但万一有人会来这里寻求解决方案。我已经创建了一个简单的类来处理它。

用法:

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;
    }
}
另一答案

方法isStillSincePress()可以与getEventType() API一起使用MouseEvent

也许你需要在MOUSE_PRESSEDMOUSE_RELEASED之间实现鼠标移动的阈值,以提高可用性。

另一答案

@wcomnisky

非常感谢您的帮助。我最后做了什么(我尝试在发布事件处理程序中使用isStillSincePress(),它似乎仍然将短距离拖动视为点击..虽然我可能做错了)是这样的:在鼠标按下处理程序我记录按坐标(也许这个想法类似于isStillSincePressed()方法..它可能是由其名称/描述建议)pressX = event.getX(); pressY = event.getY()和鼠标释放处理程序我这样做:if( (pressX == event.getX() ) && (pressY == event.getY()) ) doClickAction(); else doDragEndAction()。似乎是在工作..在拖动时处理动作,我会尝试使用通常的拖动处理程序。

以上是关于JavaFX区分拖动和单击的主要内容,如果未能解决你的问题,请参考以下文章

D3区分具有拖动行为的元素的单击和拖动

如何在 JavaFX 中的 SplitPane Divider 上检测鼠标拖动事件

区分 ng2-dragula 上的单击或拖动

单击 JavaFX 突出显示 TextField 中的所有文本

压缩/扩展 JavaFX 2 数据图表

拖动功能无法正常工作! JavaFX VBox 拖动