6

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:

Scroll glitch screenshot

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:

enter image description here

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:

  • This glitch appears in almost any scroll on Windows 8
  • It can be reproduced by scrolling using mouse wheel, but not dragging the scroll bar
  • It can be fixed by changing scroll mode in JViewport of the JScrollPane

And my questions are:

  • Can anyone confirm that this issue appears on any other OS except Windows 8?
  • What could be the real source of this issue?
  • Is there any known/good way to fix this w/o modifying scroll mode?

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.

Community
  • 1
  • 1
Mikle Garin
  • 10,083
  • 37
  • 59
  • 1. no issue in Win8, ent 64b, physical GPU (HP low_profile), stable JDK 17_021, funny JRE 17_051, 2. note ScrollMode is designatred just for Object(s) where parent is JViewPort, not (hasn't something with) JScrollPane – mKorbel May 27 '14 at 10:13
  • is possible to simulating by using Thread.sleep and Random position for JScrollBar, but caused in Java6(maybe Java5) too – mKorbel May 27 '14 at 10:15
  • Works fine in my Win7, however your code has all the rights to have any kind of weird bugs that the JVM feels like since your are breaking Swing's single threading rule. Add `invokeLater` in your main. See [Swing's Hello World](http://docs.oracle.com/javase/tutorial/displayCode.html?code=http://docs.oracle.com/javase/tutorial/uiswing/examples/start/HelloWorldSwingProject/src/start/HelloWorldSwing.java), you can find a detailed explanation of this [here](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html). – DSquare May 27 '14 at 10:23
  • @DSquare well yes, you are right, but that doesn't affect this specific issue anyhow. But anyway, i have updated the code example with proper frame initialization in EDT and issue is still there. – Mikle Garin May 27 '14 at 10:26
  • Too bad, always worth a try. – DSquare May 27 '14 at 10:27
  • @DSquare true, but I know Swing pretty well and EDT issues are starting to pop only if you have some really large UI or if you are using some weird/massive multi-threaded calls to Swing components. In other cases placing the UI initialization into EDT doesn't change anything at all. Ever. Still, I am not saying that this is a good way to do stuff, using EDT is a must in most cases :) – Mikle Garin May 27 '14 at 10:30
  • @mKorbel so... you have reproduced the issue in the end? Or did I just misunderstood your last comment? – Mikle Garin May 27 '14 at 10:31
  • I don't see the problem using Windows 7 & the scroll wheel. – Andrew Thompson May 27 '14 at 10:34
  • 1
    @Mikle Garin by blocking an EDT in very short period, by using Thread.sleep(20) and Randon from JScrollbars max value, then there is possible to see something similair, :-) restart Eclipse, update drivers for GPU, you are out of luck for on_board GPU – mKorbel May 27 '14 at 10:43
  • Probably a good idea. I also checked this on my home Windows 8.1 just now (and yes, here i have Windows 8, not 8.1) and i cannot reproduce the issue there. It seems to be some of my hardware or software problems. I will try updating stuff one-by-one and will see if it makes any effect. – Mikle Garin May 27 '14 at 10:45
  • @Mikle Garin my endless curiosity, please whats is reason for HeadlessException – mKorbel May 27 '14 at 10:46
  • No problem on Mac OS X, Java 7. – trashgod May 27 '14 at 10:46
  • @mKorbel the reason is IntelliJ IDEA autocompletion which simply copied it from super constructor `public JFrame() throws HeadlessException`, i guess no need to explain futher :) – Mikle Garin May 27 '14 at 12:22
  • 2
    In the end - the issue with this scroll glitch was actually in the unupdated OS. Though this is first time i am seeing that updates could cause such strange drawing behavior in Java application, assuming that it handles all the paintings within the frame on its own. – Mikle Garin May 27 '14 at 12:24
  • @mKorbel: NetBeans occasionally does this too. – trashgod May 27 '14 at 15:12
  • @MikleGarin: I wonder if the update included a revised video driver. – trashgod May 27 '14 at 21:13
  • @trashgod nope, video driver was the next thing i was going to update so there were only about 20-25 system updates, nothing else. – Mikle Garin May 28 '14 at 06:45
  • @MikleGarin: Perhaps one of the updates contained a regression against the existing video driver. – trashgod May 28 '14 at 17:21
  • @trashgod probably, unfortunately i don't have enough patience to look through detailed description of each update and that would most probably be pointless anyway. The main point is that this was a system/update-related issue and it can be fixed by simply keeping your system up-to-date – Mikle Garin Jun 02 '14 at 08:25
  • @MikleGarin: This seems reasonable. Should this question be closed as "caused by a problem that can no longer be reproduced?" – trashgod Jun 02 '14 at 10:37
  • @trashgod if this will still be visible for those who are looking for the solution for this issue even if topic is closed, then i guess yes – Mikle Garin Jun 02 '14 at 12:02

1 Answers1

4

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.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • I used a panel with grid layout and tons of buttons just to have the vertical scroll and some self-repainting elements inside (you can rollover button after glitch and it will be repainted). Buttons themselves and the panel can be replaced with whatever - described bug will still be there. It is just easier to see it this way. – Mikle Garin May 27 '14 at 10:54
  • And yes, with JList or JTable glitch is still there. As i said before - this bug is not scroll content -related, but some drawing or even native stuff -related. – Mikle Garin May 27 '14 at 10:59
  • If you see a similar effect with this `JTable` [example](http://stackoverflow.com/a/13919878/230513), the problem may be specific to your os/platform/version. – trashgod May 27 '14 at 11:02
  • Yes, i do have issue with those examples as well, check this screenshot: http://s7.hostingkartinok.com/uploads/images/2014/05/abef44e400e601809a525faebe6667ac.png – Mikle Garin May 27 '14 at 11:23