How to know if a JScrollBar has reached the bottom of the JScrollPane?

情到浓时终转凉″ 提交于 2019-12-01 18:28:45

You have to add the extent of the scrollbar to your calculation. I added the code into your code in the example below.

scrollPane.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() {
    @Override
    public void adjustmentValueChanged(AdjustmentEvent ae) {
        int extent = scrollPane.getVerticalScrollBar().getModel().getExtent();
        System.out.println("Value: " + (scrollPane.getVerticalScrollBar().getValue()+extent) + " Max: " + scrollPane.getVerticalScrollBar().getMaximum());
    }
});

Two alternative implementations (partially reacting to Kleopatra)

scrollPane.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() {

    @Override
    public void adjustmentValueChanged(AdjustmentEvent event) {
        JScrollBar scrollBar = (JScrollBar) event.getAdjustable();
        int extent = scrollBar.getModel().getExtent();
        System.out.println("1. Value: " + (scrollBar.getValue() + extent) + " Max: " + scrollBar.getMaximum());

    }
});

Or via the model

scrollPane.getVerticalScrollBar().getModel().addChangeListener(new ChangeListener() {

    @Override
    public void stateChanged(ChangeEvent event) {
        BoundedRangeModel model = (BoundedRangeModel) event.getSource();
        int extent = model.getExtent();
        int maximum = model.getMaximum();
        int value = model.getValue();

        System.out.println("2. Value: " + (value + extent) + " Max: " + maximum);

    }
});

@StanislavL almost had the correct answer.

Try scrollBar.getValue() == scrollBar.getMaximum() - scrollBar.getVisibleAmount().

To understand why the getVisibleAmount() call is necessary, you must first understand how JScrollBars work. A JScrollBar has 4 values: minimum, maximum, value, and extent. value is the top of the scroll handle itself, and extent is the effective length of the scroll handle. value will never equal maximum unless the scroll handle has a length of 0. To compensate, we must adjust the value we are comparing against by subtracting the length of the scroll handle to get the effective maximum.

This effect is documented here, which misleadingly makes it sound like getMaximum() adjusts the value like it should, but looking closely at the implementation of JScrollBar shows that getMaximum() actually gives us the true maximum, not the effective maximum.

By using the viewport of the JScrollPane you can calculate if the viewport is viewing the end of the component.

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


public class ViewPortDemo extends JPanel{

    public ViewPortDemo(){
        super();
        JTree tree = new JTree();
        for(int i =0; i < tree.getRowCount(); i++){
            tree.expandRow(i);
        }

        final JScrollPane pane = new JScrollPane(tree){
            Dimension prefSize = new Dimension(200,150);
            public Dimension getPreferredSize(){
                return prefSize;
            }
        };

        pane.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() {

            @Override
            public void adjustmentValueChanged(AdjustmentEvent e) {
                JViewport vp = pane.getViewport();
                if(vp.getView().getHeight() <= vp.getHeight() + vp.getViewPosition().y){
                    System.out.println("End");
                }
            }
        });

        add(pane);
    }


    public static void main(String[] args){
        final JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new ViewPortDemo());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}
scrollBar.getValue()==scrollBar.getMaximum()
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!