Windows scrollbar restriction and JavaFX
In a short time programmers were caught in manually drawing pixel-by-pixel images and text. This has all changed with the introduction of UI frameworks.
For the majority of Java developers, there is no second thought which UI framework to choose. JavaFX is one of the free and most capable UI frameworks that you can use “out of the box” and benefit from its built-in support of CSS right away. But, what you may not know is:
The whole javafx.scene.text.TextFlow, including those parts that are outside of the visible area, is rendered in real time.
In terms of the huge number of text lines that need to be cycled through by the user, you may consider some workarounds like lazy loading. At first glance, it can solve all of our problems. This may work great, but further down the line we drop this solution to the trash bin because we need to provide a smooth and seamless experience as it is one of the main requirements.
The thing is that the process of loading text by chunks in JavaFX’s javafx.scene.text.TextFlow, drawing on the scene, applying styles, repositioning it and scrolling is quite a demanding operation. This is especially true if you take into account low-end grade PCs that a future application will be used on.
To have a better understanding on a scale of texts we need to process with our solution, try to imagine javafx.scene.text.TextFlow that contains thousands of words with the total height of more than 32k pixels (about 30 times of the standard Full HD resolution).
And one more small detail...
ScrollBar components maximum precision is locked at roughly *only* 32k pixels in height on Windows.
Because of the smooth scrolling being a top priority, we could not afford inconsistent scrolling speeds or huge jumps. By all means, we were obligated to retain the speed at about 3px/25ms. So, the precision of ScrollBar was a critical factor.
Don’t forget that rendering is just a visual representation of the data and there is much more data processing to the application itself.
Things looked a bit frightful on the performance side, taking into account that we had to scroll text nearly endlessly.
Basically, we need to find a solution that would lower load on a CPU.
Tinkering with JavaFX’s renderer did not give us any solid ground for moving any further than the demo stage. Lazy loading also wasn’t the ideal solution as I have mentioned above.
Finally, we decided to look for an alternative for JavaFX UI framework.
With a deep research done, we managed to narrow down the list of contenders to two entries that would fit our project the most.
And this is what we’ve learned from it:
Electron is even more system heavy than JavaFX and it requires more time to transfer the application to this framework. So, we have no need to look further than that.
SWT (or Standard Widget Toolkit), however, positions itself as a lightning-fast and highly customizable framework which works with native UI calls. At this point, we decided to roll with it and started the migration to the SWT.
We used org.eclipse.swt.custom.StyledText component due to its renderer implementation. StyledText doesn’t draw the whole text as a single unit, but only the visible part in the client area. Thus, we can be sure that scrolling time remains constant and that we don’t lose the opportunity to apply styles for pieces of text if needed.
Sure, this wasn’t the last time our team battled with the UI optimization, but since then we’ve grown stronger in our knowledge and are ready for the challenges ahead!