提问者:小点点

ScrollBar在Swing的JScrollpane中移动不平滑


我有这样的情况。我有一个scrollpane,它的viewportView是一个JPanel,而那个JPanel的布局是BoxLayout。在此面板中,我添加了一个扩展JPanel的类,该类包含JComponents。

因此,在运行应用程序时,JComponents显示在JScrollPane中。这就是我的ScrollPane的形成方式。

这里的问题是,当数据超过750行左右时,滚动条开始出现问题。当鼠标滚轮向上或向下滚动时,滚动不平滑,它突然在中间停止并再次开始,说它有一个不稳定的移动。我的问题是在这种情况下,我如何才能获得平滑的鼠标移动。

我的卷轴是这样的

public JScrollPane getScrollPane() {
    if (scrollPane == null) {
        scrollPane = new JScrollPane();
        scrollPane.setSize(new Dimension(1000, 433));
        scrollPane.setLocation(new Point(10, 10));
        scrollPane.setColumnHeaderView(getHeaderOfRowPanel());
        scrollPane
                .setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
        scrollPane.setViewportView(getScrollPanel());
        scrollPane
                .setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        scrollPane.getVerticalScrollBar().setUnitIncrement(
                unitIncrement);

    }
    return scrollPane;
}

private JPanel getScrollPanel() {
    if (scrollPanel == null) {
        scrollPanel = new JPanel();
        scrollPanel.setBorder(null);
        scrollPanel.setLayout(new BoxLayout(getScrollPanel(),
                BoxLayout.Y_AXIS));
    }
    return scrollPanel;
}


private class RowPanel extends JPanel {
//My components are here ..
//I add this Panel in scrollPanel
}

共3个答案

匿名用户

查看JScrollBar. setUnit增量,因为JScolPane中的一堆JPanelsJListJTableJTextArea相比un_natural滚动

示例

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class JScrollBarUnitIncrement {

    public static void main(String[] args) {
        final JFrame f = new JFrame("");
        JPanel panel = new JPanel();
        panel.setLayout(new GridLayout(2000, 1));
        for (int i = 0; i != 2000; i++) {
            JButton btn = new JButton("Button 2");
            panel.add(btn);
        }
        final JScrollPane sPane = new JScrollPane(panel);
        final int increment = 50;
        sPane.getVerticalScrollBar().setUnitIncrement(increment);
        KeyStroke kUp = KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0);
        KeyStroke kDown = KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0);
        sPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(kUp, "actionWhenKeyUp");
        sPane.getActionMap().put("actionWhenKeyUp", new AbstractAction("keyUpAction") {

            private static final long serialVersionUID = 1L;

            public void actionPerformed(ActionEvent e) {
                final JScrollBar bar = sPane.getVerticalScrollBar();
                int currentValue = bar.getValue();
                bar.setValue(currentValue - increment);
            }
        });
        sPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(kDown, "actionWhenKeyDown");
        sPane.getActionMap().put("actionWhenKeyDown", new AbstractAction("keyDownAction") {

            private static final long serialVersionUID = 1L;

            public void actionPerformed(ActionEvent e) {
                final JScrollBar bar = sPane.getVerticalScrollBar();
                int currentValue = bar.getValue();
                bar.setValue(currentValue + increment);
            }
        });
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(sPane);
        f.pack();
        SwingUtilities.invokeLater(new Runnable() {

            public void run() {
                f.setVisible(true);
            }
        });
    }

    private JScrollBarUnitIncrement() {
    }
}

匿名用户

在JScrollPane中填充如此巨大的行数从来都不是好事。因为,根据scrollpane的高度和RowPanel的高度,可见部分仅在视口中大约20到30行。那么,为什么要一次填充如此巨大的行呢?平滑度的问题是因为可能会有异常(参见控制台)。所以,解决这个问题,我看到两个选项给你。一个是使用分页,另一个是允许用户输入一些搜索条件来过滤掉不需要的记录。

匿名用户

正如@mKorbel所指出的,JTableJList都实现了Scrollable以实现方便的滚动增量,并且它们都使用轻量级模式来提高渲染速度。如果您不能直接使用任何一个组件,您仍然可以使用这些模式。本教程包括Scrollable示例,这里有一个CellRendererPane示例。