JScrollPane - 滚动时的视觉故障

时间:2014-05-27 09:51:48

标签: java swing jscrollpane

在JScrollPane中有一些关于类似故障的主题,同时滚动如下:

但他们缺乏SSCCE和案件的一些解释,所以我将添加缺少的东西。

首先,这是一个在纯Swing上编写的小例子,没有使用第三方代码:

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 );
            }
        } );
    }
}

这是一个小例子 - 顶部和底部有两个面板,并在框架中间滚动了大量内容。所以,这是在这个特定的例子中毛刺的样子:

Scroll glitch screenshot

要重现它:您必须使用仅鼠标滚轮向下滚动JScrollPane,通过拖动滚动条滚动不会导致此问题,可能是由于大量重绘量或其他一些细微差别。滚动时,您会看到与按钮重叠的白线。在BLIT_SCROLL_MODE JScrollPane中,只需复制之前绘制的部分,以最大限度地提高滚动速度并最大限度地减少使用的RAM,但它似乎有某种错误。

使效果更加惊人&#34;恐怖&#34;你可以提高滚动速度:

scroll.getVerticalScrollBar ().setUnitIncrement ( 30 );

滚动一段时间后你会看到类似的内容:

enter image description here

当我从Windows 7切换到Windows 8时,这个故障第一次出现,所以这似乎也是一些与Windows 8相关的问题。它可以在Windows 8系统上使用任何版本的JDK(6/7/8)进行复制。我不确定这是否可以在其他系统上重现。

还有一个观察 - 类似的问题似乎出现在Windows 8上甚至与Java无关的应用程序中。例如,我在Skype聊天窗口中已经多次看到这个问题,有时在文本编辑器和其他使用滚动的应用程序中。与此同时,所有这些应用程序(相同版本)在其他版本的Windows上都没有此问题。

所以这可能是Windows 8的一般问题,但我无法100%确定,因为它有一个简单的(但实际上不是很好的)代码解决方法:

scroll.getViewport ().setScrollMode ( JViewport.BACKINGSTORE_SCROLL_MODE );
scroll.getViewport ().setScrollMode ( JViewport.SIMPLE_SCROLL_MODE );

使用其中一种滚动模式而不是JViewport.BLIT_SCROLL_MODE(在Swing中设置为默认滚动模式,因为它最有效)解决了这个问题。使用JViewport.BACKINGSTORE_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;

总结:

  • 此故障几乎出现在Windows 8上的任何滚动
  • 可以使用鼠标滚轮滚动,但不能拖动滚动条
  • 可以通过更改JScrollPane的JViewport
  • 中的滚动模式来修复它

我的问题是:

  • 任何人都可以确认此问题出现在除Windows 8以外的任何其他操作系统上吗?
  • 这个问题的真正原因是什么?
  • 是否有任何已知/好方法可以修复此修改滚动模式?

更新1

由于此问题似乎特定于我的硬件/软件,我将尝试更新各种内容(系统,视频驱动程序,进行一些清理)。但是对于那些遇到同样问题的人来说,这仍然有用,所以如果我能理解究竟是什么导致了这个问题以及如何修复它,我会发布更多更新。


更新2

安装了十几个Windows更新(Windows仍然只有8个,而不是8.1个)后,这个问题就消失了。我不确定哪个更新确切地解决了这个问题,但肯定是一些系统核心更新。因此,如果您使用的是早期版本的Windows 8而没有安装最新更新,则基本上会出现此问题。

1 个答案:

答案 0 :(得分:4)

虽然GridLayout(0, 1)可以在列中排列任意数量的组件,但结果对于超过几百个单元格而言难以扩展。 Profile可以肯定。相反,请使用仅根据建议here呈现可见单元格的组件,例如JListJTable