How to make JScrollPane scroll 1 line per mouse wheel step?

前端 未结 2 763
独厮守ぢ
独厮守ぢ 2021-01-05 17:05

I have a JScrollPane whose content pane is a JXList. When I use the mouse wheel on the list, the list steps three (3) items at a time. This also works for a table, regardles

2条回答
  •  执念已碎
    2021-01-05 17:52

    Out of pure interest (and a little boredom) I created a working example:

    /**
     * Scrolls exactly one Item a time. Works for JTable and JList.
     *
     * @author Lukas Knuth
     * @version 1.0
     */
    public class Main {
    
        private JTable table;
        private JList list;
        private JFrame frame;
    
        private final String[] data;
    
        /**
         * This is where the magic with the "just one item per scroll" happens!
         */
        private final AdjustmentListener singleItemScroll = new AdjustmentListener() {
            @Override
            public void adjustmentValueChanged(AdjustmentEvent e) {
                // The user scrolled the List (using the bar, mouse wheel or something else):
                if (e.getAdjustmentType() == AdjustmentEvent.TRACK){
                    // Jump to the next "block" (which is a row".
                    e.getAdjustable().setBlockIncrement(1);
                }
            }
        };
    
        public Main(){
            // Place some random data:
            Random rnd = new Random();
            data = new String[120];
            for (int i = 0; i < data.length; i++)
                data[i] = "Set "+i+" for: "+rnd.nextInt();
            for (int i = 0; i < data.length; i+=10)
                data[i] = ""+data[i]+"
    Spacer!"; // Create the GUI: setupGui(); // Show: frame.pack(); frame.setVisible(true); } private void setupGui(){ frame = new JFrame("Single Scroll in Swing"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JSplitPane split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); frame.add(split); // Add Data to the table: table = new JTable(new AbstractTableModel() { @Override public int getRowCount() { return data.length; } @Override public int getColumnCount() { return 1; } @Override public Object getValueAt(int rowIndex, int columnIndex) { return data[rowIndex]; } }); for (int i = 0; i < data.length; i+=10) table.setRowHeight(i, 30); JScrollPane scroll = new JScrollPane(table); // Add out custom AdjustmentListener to jump only one row per scroll: scroll.getVerticalScrollBar().addAdjustmentListener(singleItemScroll); split.add(scroll); list = new JList(data); scroll = new JScrollPane(list); // Add out custom AdjustmentListener to jump only one row per scroll: scroll.getVerticalScrollBar().addAdjustmentListener(singleItemScroll); split.add(scroll); } public static void main(String[] agrs){ new Main(); } }

    The real magic is done in the custom AdjustmentListener, where we go and increase the current "scroll-position" by one single block per time. This works up and down and with different row-sizes, as shown in the example.


    As @kleopatra mentioned in the comments, you can also use a MouseWheelListener to only redefine the behavior of the mouse-wheel.

    See the official tutorial here.

提交回复
热议问题