0

I am developing a JavaFX project and I need something similar to a TouchEvent that characterizes a "push and hold" event. But It should be mapped as a MouseEvent because I'm having troubles with touch events on Linux. For instance, in Ubuntu, it won't respond to touch events.

Please, let me know if you have any ideas about how to fire a MouseEvent whenever a "push and hold" occurs on Linux?

Teocci
  • 4,348
  • 1
  • 34
  • 36
  • Isn't a click and hold just a mouse press without a mouse release? – MadProgrammer Sep 01 '14 at 08:02
  • yes, but the mouse will take it as drag detected event. – Mouhammad.Nexus Sep 01 '14 at 08:03
  • I haven't tried, but wouldn't a drag event only be triggered if the mouse was moved...which it would then be a drag event, but still a mouse release needs to be triggered...probably missing something really obvious – MadProgrammer Sep 01 '14 at 08:07
  • MR.@MadProgrammer there is nothing to be missed!!! once you clicked the mouse it activates "onmouseclicked" event and it fires it when the mouse button is released, if the mouse moves it fires the "ondragdetected" and if the mouse button is released after the motion it fires the "ondragdropped" event, and i need to achieve "push and hold" event, So after that please before answering get some knowledge about the subject then reread the question. – Mouhammad.Nexus Sep 01 '14 at 08:26

1 Answers1

9

Just use a PauseTransition as a timer for the "hold". Start it if the mouse is pressed, stop it if it's released or dragged.

import javafx.animation.PauseTransition;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
import javafx.util.Duration;

public class MousePressAndHoldTest extends Application {

    @Override
    public void start(Stage primaryStage) {
        Pane root = new Pane();

        addPressAndHoldHandler(root, Duration.seconds(1), 
                event -> System.out.println("Press and hold"));


        primaryStage.setScene(new Scene(root, 400, 400));
        primaryStage.show();
    }

    private void addPressAndHoldHandler(Node node, Duration holdTime, 
            EventHandler<MouseEvent> handler) {

        class Wrapper<T> { T content ; }
        Wrapper<MouseEvent> eventWrapper = new Wrapper<>();

        PauseTransition holdTimer = new PauseTransition(holdTime);
        holdTimer.setOnFinished(event -> handler.handle(eventWrapper.content));


        node.addEventHandler(MouseEvent.MOUSE_PRESSED, event -> {
            eventWrapper.content = event ;
            holdTimer.playFromStart();
        });
        node.addEventHandler(MouseEvent.MOUSE_RELEASED, event -> holdTimer.stop());
        node.addEventHandler(MouseEvent.DRAG_DETECTED, event -> holdTimer.stop());
    }


    public static void main(String[] args) {
        launch(args);
    }
}
James_D
  • 177,111
  • 13
  • 247
  • 290
  • now i have a problem that i have on the same node a "dragdetected" event handler and there is some complexity, so cutting to the chase when the timer is finished (the timer in your code) i want the application to release the mouse button so the handler of the "dragdeteted" won't work. – Mouhammad.Nexus Sep 03 '14 at 10:16
  • I can't see a nice way to do that - I think you just have to set a flag to true when the timer finishes, reset it to false in the mouse released listener, and check it in your drag detected, only acting if the flag is false. – James_D Sep 03 '14 at 12:38