Skip to content
Advertisement

JavaFX event on Mouse Wheel Finished for ScrollPane

I have a ScrollPane with lots of elements on it, (Same one as this JavaFX setHgrow / binding property expanding infinitely) and initially I was planning on using the setOnScrollFinished(this::scrollFinished); event, however I’ve now discovered through research that this only applies to touch gestures, and trying to find a compromise for the MouseWheel hasn’t been great and I just find very complicated solutions which don’t really solve what I need.

The most I have is adding a listener to the scroll bar changing:

JavaScript

However this continuously fires while scrolling, what I’m looking for is something which will only call after, lets say, it’s been a second since I’ve stopped scrolling.

My ultimate goal is to have a system where when I scroll, it will run an event which will go through each of my elements so I can assign an image to them if they’re within the window bounds, and them remove the image if they’re not.

This is essentially my code, taken from the nice user who helped me out before:

JavaScript

Advertisement

Answer

You will have to listen for property changes to detect scrolling without missing. You don’t have to take heavy action each time the listener triggers though: just record the time when it happened, and then have a loop filter out and fire the event when needed. This goes:

  1. Register any time the scroll values change (or the ScrollPane is resized)
  2. Setup a loop that will check on short intervals (from a user perspective) if a change was registered more than 1 second ago.
  3. When this happens, have the ScrollPane fire an event – let’s call this a “tick”- and un-register last scroll

For the loop, we’ll use a Timeline which KeyFrames will have a onFinished handler called on the JavaFX application thread about every 100ms, in order to avoid having to deal with another thread.

JavaScript

If your ScrollPane is to be removed from the scene at any point, you might want to add a method to stop the TimeLine to avoid it continuing to run and possibly consuming memory.

Full runnable demo code:

JavaScript
User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement