【问题标题】:ScrollBar movement not smooth in JScrollpane in SwingSwing 中的 JScrollpane 中的 ScrollBar 移动不平滑
【发布时间】:2012-06-25 04:30:09
【问题描述】:

我有这样的情况。 我有 viewportView 是 JPanel 的滚动窗格 并且 JPanel 的布局为 BoxLayout。在这个面板中,我添加了一个扩展 JPanel 的类,该类包含 JComponents。

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

这里的问题是,当数据超过大约 750 行时,滚动条开始出现问题。 用鼠标滚轮上下滚动时,滚动不流畅,中间突然停了又开始,说是有生涩的动作。 我的问题是如何在这种情况下获得平滑的鼠标移动。

我的scrollPane是这样的

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
}

【问题讨论】:

    标签: java swing jscrollpane


    【解决方案1】:

    看看JScrollBar.setUnitIncrement,因为JScollPane 中的JPanelsJListJTableJTextArea 相比具有不自然的滚动效果

    例子

    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() {
        }
    }
    

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        【解决方案3】:

        正如@mKorbel 所说,JTableJList implement Scrollable 都用于方便滚动增量,它们都使用flyweight pattern 来实现rendering 速度。如果您不能直接使用任一组件,您仍然可以使用这些模式。教程包括Scrollable 示例,还有一个CellRendererPane 示例here

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-09-30
          • 1970-01-01
          • 2014-02-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-12-05
          相关资源
          最近更新 更多