Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ScrollBar movement not smooth in JScrollpane in Swing

I have a situation like this. I have scrollpane whose viewportView is a JPanel And that JPanel has the layout as BoxLayout. In this panel I add one class which extends JPanel and that class contains JComponents.

So while running an application, the JComponents are shown in the JScrollPane. This is how my ScrollPane is formed.

The problem here is, When the data exceeds more than around 750 rows, The scrollbar starts giving problems. When scrolling up or down by mouse wheel, scroll doesnot move smoothly, It suddenly stops in the middle and again starts, say it has a jerky movement. my Question is how can i get the smooth mouse movement in this scenario.

My scrollPane is like this

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
}
like image 775
Sunil luitel Avatar asked Dec 06 '25 20:12

Sunil luitel


2 Answers

Have look at JScrollBar.setUnitIncrement, beacuse bunch of JPanels in the JScollPane has un_natural scrolling in compare with JList, JTable or JTextArea

example

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() {
    }
}
like image 125
mKorbel Avatar answered Dec 08 '25 10:12

mKorbel


It is never good to populate such huge no. of rows in JScrollPane. Because, the visible portion is only around let's say 20 to 30 rows in viewport depending on the height of the scrollpane and the height of your RowPanel. So, why to populate such huge rows at once ? The problem with the smoothness is because there might be exception (see the console ). So, resolve this, I see two options for you. One is to use pagination and another is to allow users to enter some search criteria to filter out the unwanted records.

like image 33
Manoj Shrestha Avatar answered Dec 08 '25 09:12

Manoj Shrestha



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!