3
votes

I have multiple Labels. I have an EventHandler<MouseEvent> that launches a method (opens a dialog) when the Label is clicked (setOnMouseClicked).

However, I have also implemented a setOnMousePressed/setOnMouseDragged method using EventHandler to make the Label draggable.

My problem is, when I release the mouse after the drag, the method for mouse clicked is called and the dialog opens. Is there a way to differentiate these two events (i.e. when dragged, don't call click)? Or is the only way to switch to a different component (Button) so I can differentiate between MouseEvent and ActionEvent?

2
*typo in line (i.e. when dragged, don't call click) - sandboxj
Edit your question to fix the typo. - James_D

2 Answers

4
votes

Use one EventHandler for any MouseEvent and filter click events if a drag occurred. For instance :

public class MyHandler implements EventHandler<MouseEvent> {

    private final EventHandler<MouseEvent> onDraggedEventHandler;

    private final EventHandler<MouseEvent> onClickedEventHandler;

    private boolean dragging = false;

    public Handler(EventHandler<MouseEvent> onDraggedEventHandler, EventHandler<MouseEvent> onClickedEventHandler) {
        this.onDraggedEventHandler = onDraggedEventHandler;
        this.onClickedEventHandler = onClickedEventHandler;
    }

    @Override
    public void handle(MouseEvent event) {
        if (event.getEventType() == MouseEvent.MOUSE_PRESSED) {
            dragging = false;
        }
        else if (event.getEventType() == MouseEvent.DRAG_DETECTED) {
            dragging = true;
        }
        else if (event.getEventType() == MouseEvent.MOUSE_DRAGGED) {
            //maybe filter on dragging (== true)
            onDraggedEventHandler.handle(event);
        }
        else if (event.getEventType() == MouseEvent.MOUSE_CLICKED) {
            if (!dragging) {
                onClickedEventHandler.handle(event);
            }
        }

    }
}

Then add it to the button :

button.addEventHandler(MouseEvent.ANY, 
                       new MyHandler(
                           e -> System.out.println("Dragged"), 
                           e -> System.out.println("Clicked"))
                       );
1
votes

Perhaps by using another eventhandler or filter, first an specific than a generic one.

StackPane root = new StackPane();
root.addEventFilter(MouseEvent.MOUSE_PRESSED, 
 new EventHandler<MouseEvent>() {
 @Override
 public void handle(final MouseEvent event) {
  if(event.getEventType() == MouseEvent.MOUSE_PRESSED)
   //do something
 }
});

// or using MouseEvent.ANY in another eventhandler.
// registering an own eventdispatcher.