简体   繁体   English

JavaFX区分拖放

[英]JavaFX distinguish Drag and Click

I'm trying to do the following in JavaFX. 我正在尝试在JavaFX中执行以下操作。 I am using Canvas to draw stuff on the screen and I want the following to happen: 我正在使用Canvas在屏幕上绘制东西,我希望发生以下情况:

When I click on the Canvas surface (like fast press and release): something happens 当我单击“画布”表面时(例如快速按下并释放):发生了某些事情

When I drag on the Canvas surface (like press and move, then release): something ELSE happens 当我在“画布”表面上拖动时(例如按住并移动,然后松开):发生了其他事件

BUT I want it to exclude the click action if I drag, so if I drag, what would have happened if I clicked should not happen. 但是,我希望它在我拖动时不包含单击动作,因此,如果拖动,则单击时不会发生什么。 Sadly, it seems like when I release the mouse, both release and click events launch, even if I drag. 令人遗憾的是,即使我拖动鼠标,释放鼠标和单击事件时,似乎都将它们释放。

The method isStillSincePress() can be used together with the getEventType() , both from the MouseEvent API. 方法isStillSincePress()可以与MouseEvent API中的getEventType()一起使用。

Maybe you'll need to implement a threshold for the mouse movement between the MOUSE_PRESSED and MOUSE_RELEASED to improve the usability. 也许您需要为MOUSE_PRESSEDMOUSE_RELEASED之间的鼠标移动实现阈值,以提高可用性。

It's a bit late, but in case someone will come here for a solution. 有点晚了,但万一有人来这里寻求解决方案。 I've created a simple class to handle it. 我创建了一个简单的类来处理它。

Usage: 用法:

clickNotDragDetectingOn(yourNode)
        .withPressedDurationTreshold(150)
        .setOnMouseClickedNotDragged((mouseEvent) -> {
            // logic here
        });

Code: 码:

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;
    }
}

@wcomnisky @wcomnisky

Thank you very much for your help. 非常感谢您的帮助。 What I did in the end (I tried using isStillSincePress() in the release event handler and it seemed it was still treating short distance drags as clicks.. though I may have done something wrong) was this: in the mouse press handler I record press coordinates (maybe this idea is similar to the isStillSincePressed() method.. it may have been suggested by its name / description) pressX = event.getX(); pressY = event.getY() 最后我做了什么(我尝试在发布事件处理程序中使用isStillSincePress(),似乎它仍将短距离拖动视为单击。尽管我可能做错了什么)是这样的:在鼠标按下处理程序中,我记录了按下坐标(也许这个想法类似于isStillSincePressed()方法。它的名称/描述可能已经暗示了它) pressX = event.getX(); pressY = event.getY() pressX = event.getX(); pressY = event.getY() and in the mouse release handler I do this: if( (pressX == event.getX() ) && (pressY == event.getY()) ) doClickAction(); else doDragEndAction() pressX = event.getX(); pressY = event.getY()然后在鼠标释放处理程序中执行以下操作: if( (pressX == event.getX() ) && (pressY == event.getY()) ) doClickAction(); else doDragEndAction() if( (pressX == event.getX() ) && (pressY == event.getY()) ) doClickAction(); else doDragEndAction() . if( (pressX == event.getX() ) && (pressY == event.getY()) ) doClickAction(); else doDragEndAction() Seems to be workin.. for handling actions while dragging, I'll try using the usual drag handler. 似乎在工作..用于在拖动时处理动作,我将尝试使用常规的拖动处理程序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM