lolero
lolero

Reputation: 1273

How to detect if the source of a scroll or mouse event is a trackpad or a mouse in JavaFX?

This is basically the same question as this one but with JavaFX instead of java swing:

I want to know if a scroll event is generated by the trackpad or a mouse in JavaFX.

Upvotes: 2

Views: 1476

Answers (1)

Max
Max

Reputation: 11

According to a documentation on ScrollEvent there is a subtle difference in handling scroll events from mouse and trackpad.

When the scrolling is produced by a touch gesture (such as dragging a finger over a touch screen), it is surrounded by the SCROLL_STARTED and SCROLL_FINISHED events.

Having that in mind you can track SCROLL_STARTED and SCROLL_FINISHED events and modify your SCROLL_EVENT handler in between these two boundaries. However the trackpad can send SCROLL_EVENTs after SCROLL_FINISHED being sent (scrolling inertia) so you can check out the event.isInertia() method to filter these events.

Due to a probable bug in JavaFX in rare cases SCROLL_EVENTs may occur after SCROLL_FINISHED with event.isInertia() == false (if you scroll on a trackpad very quickly many many times). The possible workaround is to track the timestamp of the last SCROLL_FINISHED event and to ignore these "ghost" events within short time period after that timestamp.

Example code:

long lastFinishedScrollingTime;
boolean trackpadScrolling;

node.setOnScroll(event -> {
    long timeDiff = System.currentTimeMillis() - lastFinishedScrollingTime;
    boolean ghostEvent = timeDiff < 1000; // I saw 500-700ms ghost events
    if (trackpadScrolling || event.isInertia() || ghostEvent) {
        // trackpad scrolling
    } else {
        // mouse scrolling
    }
});

node.setOnScrollStarted(event -> {
    trackpadScrolling = true;
});

node.setOnScrollFinished(event -> {
    trackpadScrolling = false;
    lastFinishedScrollingTime = System.currentTimeMillis();
});

Upvotes: 1

Related Questions