Smooth scrolling
This PR adds smooth scrolling, as used in modern Web browsers, to FlatLaf. (issue #50)
Instead of simply painting scroll pane content at new view position, smooth scrolling animates the painting so that it looks like the content is "moving" to the new view position.

Please try this with real world applications (on various platforms if possible) and give feedback. Thanks.
Current state:
- rotating mouse wheel does smooth scrolling
- clicking on scroll bar track (or arrows if visible) does smooth scrolling
- pressing keys that scroll (e.g. PageUp, Home, etc) do smooth scrolling
Smooth scrolling is enabled by default.
Can be disabled for the whole application (at any time) with (e.g. via some Settings dialog):
UIManager.put( "ScrollPane.smoothScrolling", false );
Or via system property:
System.setProperty( "flatlaf.smoothScrolling", "false" );
Or at command line with:
-Dflatlaf.smoothScrolling=false
Can be disabled for single scroll panes (at any time) with:
myScrollPane.putClientProperty( "JScrollPane.smoothScrolling", false );
It is also possible to customize the animation by changing the duration of the scroll animation and the resolution (time between repaints). Both values are in milliseconds. E.g.
UIManager.put( "ScrollPane.smoothScrolling.duration", 500 );
UIManager.put( "ScrollPane.smoothScrolling.resolution", 20 );
Default duration is 200ms and default resolution is 10ms.
I've tested this on a 5000 row JTable (real world application) on Windows 10, haven't seen any issues wither either mouse scrolling or pressing on the scroll bar track.
However when holding down the arrows on the scroll bar (I have enabled them), 'smooth scrolling' looks jittery compared to non 'smooth scrolling'
With smooth scrolling
Without smooth scrolling (using 0.39)

@grimlock81 thx for your feedback. Have to look at how to improve arrow button scrolling. There are two timers involved (arrow button repeating and scroll animation), which do not play well together...
Arrow button scrolling is now less jittery (but not perfect, I think).
Smooth scrolling with keyboard is now implemented.
Works for all keys that do any kind of scrolling.
It works perfect for non-repeating scrolling,
but for repeating block (page) scrolling (e.g. hold down PageUp key) the speed depends on the used view component:
-
JListandJTablesame speed as with smooth scrolling disabled (plus 200 milliseconds for the scroll animation) -
JTree,JTextArea,JTextPane~~about 2x slower with smooth scrolling enabled~~ (fixed in commit 542e7d5f60c863770d657ec88a430ca0fedae70c) -
JEditorPane~~about 2x - 3x slower (depending on number of wrapped lines)~~ (fixed in commit 542e7d5f60c863770d657ec88a430ca0fedae70c)
This needs some improvements.
Repeating unit (line) scrolling (e.g. hold down Up key) works with same speed on all components and with smooth scrolling enabled or disabled.
I am really interest in this feature. I am willing to play with it, test it on our intensive application and eventually experiment code changes if needed. We are currently using the latest official version of FlatLaf. This PR is marked as having conflicts... Would it be possible to bring it up-to-date with all the changes so that I can experiment?
I experimented with this smooth-scrolling implementation. I first ported the few changes to the current code because the PR has some conflicts. The result of this port is FlatLaf-smooth-scrolling00.patch in the zip below (I only patched flatlaf-core).
I tested it on our real world app and found several problems (I am using Windows 10 with Java 17). I then created a self-contained test case (SmoothScrollingTest.java in the zip) to experiment with these problems.
I fixed some of these problems and created the improved FlatLaf-smooth-scrolling01.patch.
The root cause of the problems is that calls to JViewPort.setViewPosition() result in an immediate painting using blitting (meaning it is not handled later by the RepaintManager). So the adjustments that set the target value on the scroll bar before the timer kicks in result in a visible jump to an incorrect location. With my example and using the first patch, scrolling with the wheel when a selection is active makes the problem more visible. Another way is to use ctrl+up/down with a line that is selected and it is clear that the selection is sometimes painted at the wrong location.
I worked around most of the problems by changing (and then restoring) the blitting mode around the chunks that we know result in a call to JViewPort.setViewPosition() so that the blitting optimized repaint does not happen (but it will for the timed movements). This approach fixed mouse wheel, and I also added this pattern to fix keyboard navigation for trees. I haven't fixed table keyboard navigation because these are triggered by handlers declared in BasicTableUI and I am not sure how to wrap their call with the blitting mode swap.
Please let me know what you think, if you see the scrolling artifacts I am describing, and if you have some ideas to fix table artifacts with keyboard navigation.
Zip file: FlatLaf-smooth-scrolling.zip
This PR is marked as having conflicts... Would it be possible to bring it up-to-date with all the changes so that I can experiment?
Sure, I've rebased all commits in this PR to current main branch. Sorry for the delay.
... if you see the scrolling artifacts I am describing ...
Yes, I see the scrolling artifacts too. And temporary disabling blitting mode seem indeed fix them. Many thanks for that tip 👍 🥇 Have added parts of your code to this PR in commit 91e318f52181df076e39bf5a6867802f3c551d7c
Will have a closer look at your PR #683 next week...
The too slow repeating block (page) scrolling (e.g. hold down PageUp key) for Tree, TextArea, TextPane and EditorPane is fixed in commit 542e7d5f60c863770d657ec88a430ca0fedae70c
Fixed jittery repeating-scrolling with PageUp/Down keys when reaching the top/bottom/left/right of the viewport in commit c529dcb747a548e5a5ec95518624f51277242927.
Following screenshot shows the difference in the chart, which shows the scrollbar value. The curve shows the animated change of the scroll bar value when holding down the PageDown key and scrolling from top to bottom. The "down-pikes" are the temporary scroll bar value changes made before animation starts/continues.
Before this change, there were significant gaps in the curve, which resulted in jittery scrolling.