There were a few topics about similar glitches in JScrollPane while scrolling like:
But they lack SSCCE and some explanation on the case, so i will add what is missing.
First of all, here is a small example written on pure Swing with no 3rd-party code used:
public class ScrollGlitchExample extends JFrame
{
public ScrollGlitchExample () throws HeadlessException
{
super ();
final JPanel top = new JPanel ();
top.setPreferredSize ( new Dimension ( 300, 50 ) );
top.setBorder ( BorderFactory.createLineBorder ( Color.BLACK ) );
add ( top, BorderLayout.NORTH );
final JPanel panel = new JPanel ( new GridLayout ( 500, 1 ) );
for ( int i = 0; i < 500; i++ )
{
panel.add ( new JButton ( "button" + i ) );
}
final JScrollPane scroll = new JScrollPane ( panel );
scroll.setPreferredSize ( new Dimension ( 300, 300 ) );
add ( scroll, BorderLayout.CENTER );
final JPanel bottom = new JPanel ();
bottom.setPreferredSize ( new Dimension ( 300, 50 ) );
bottom.setBorder ( BorderFactory.createLineBorder ( Color.BLACK ) );
add ( bottom, BorderLayout.SOUTH );
setDefaultCloseOperation ( WindowConstants.EXIT_ON_CLOSE );
pack ();
setLocationRelativeTo ( null );
}
public static void main ( final String[] args )
{
SwingUtilities.invokeLater ( new Runnable ()
{
@Override
public void run ()
{
new ScrollGlitchExample ().setVisible ( true );
}
} );
}
}
This is a small example - two panels at top and bottom and scroll with lots of content in the middle of the frame. So, here is how the glitch looks like in this specific example:
To reproduce it: You will have to scroll down the JScrollPane using mouse wheel only, scrolling by dragging the scroll bar does not cause this issue, probably due to massive amount of repaints or some other minor difference. While scrolling you will see white lines overlapping the buttons. In BLIT_SCROLL_MODE JScrollPane simply copying parts painted before to maximize the speed of scrolling and minimize used RAM, but it seems to have some kind of bug.
To make the effect even more "horrifying" you can increase scrolling speed:
scroll.getVerticalScrollBar ().setUnitIncrement ( 30 );
And you will see something like this after scrolling for some time:
This glitch first time appeared when i switched from Windows 7 to Windows 8, so this also seems to be some Windows 8 -related issue. It can be reproduced using any version of JDK (6/7/8) on Windows 8 system. I am not sure whether or not this can be reproduced on other systems.
One more observation - similar issue seems to appear in applications on Windows 8 not even related to Java. For example i have seen this issue a lot of times in Skype chat window, sometimes in text editors and other applications which use scrolling a lot. At the same time all those applications (the same versions) do not have this issue on other versions of Windows.
So this is probably some general Windows 8 issue, but i cannot be 100% sure since there is a simple (but not actually a good) code workaround to it:
scroll.getViewport ().setScrollMode ( JViewport.BACKINGSTORE_SCROLL_MODE );
scroll.getViewport ().setScrollMode ( JViewport.SIMPLE_SCROLL_MODE );
Using one of these scroll modes instead of JViewport.BLIT_SCROLL_MODE (which is set as default scroll mode in Swing since it is most efficient) fixes the issue. Using JViewport.BACKINGSTORE_SCROLL_MODE instead of default mode could be the best workaround meanwhile but it is still a workaround and also has some cons described in comment to this scroll mode:
/**
* Draws viewport contents into an offscreen image.
* This was previously the default mode for <code>JTable</code>.
* This mode may offer advantages over "blit mode"
* in some cases, but it requires a large chunk of extra RAM.
*
* @see #setScrollMode
* @since 1.3
*/
public static final int BACKINGSTORE_SCROLL_MODE = 2;
To summ up:
And my questions are:
Update 1
Since this issue seems to be specific for my hardware/software i will try to update various stuff (system, video drivers, do some cleanup). But this still might be useful to those who have encountered the same issue, so i will post more updates if i will understand what exactly caused this issue and how it can be fixed.
Update 2
After installing a dozen of Windows updates (Windows is still just 8, not 8.1) this issue is gone. I am not sure which update exactly fixed this issue, but it was certainly some of system core updates. So basically this issue can happen if you are using an early version of Windows 8 without most recent updates installed.
While GridLayout(0, 1)
can arrange an arbitrary number of components in a column, the result scales poorly for more than a few hundred cells. Profile to be sure. Instead, use a component that renders only visible cells, such as JList
or JTable
, as suggested here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With