JScrollPane滚动限制已达到事件

时间:2017-05-23 09:41:56

标签: java swing jtable jscrollpane

我将JTable包裹在JScrollPane中。当我滚动到顶部或底部并继续滚动时,我希望能够检测到这一点,以便可能在开头或结尾加载更多项目,因为一次加载所有项目太昂贵/不实用。 AdjustmentListener未移动时(例如,当它已位于顶部或底部时),JScrollPane不会被触发:

scrollPane.getVerticalScrollBar().addAdjustmentListener(adjustmentEvent ->
{
    int value = adjustmentEvent.getValue();
    System.out.println(value); // Prints 0 e.g. when the top has been reached
});

但是,即使已经到达结束/开始,我也需要知道用户何时滚动。

如何做到这一点?

1 个答案:

答案 0 :(得分:3)

我建议在滚动窗格的JViewport上使用更改侦听器。以下示例显示了如何继续。请注意,shouldCheck可能用于防止错误通知(在我的示例顶部在启动时打印三次。如果您运行示例并将滑块移动到顶部和底部,则会打印相应的文本。

Screenshot with running sample

package com.thomaskuenneth;

import javax.swing.*;

public class Main {

    static boolean shouldCheck = true;

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame f = new JFrame("Demo");
            f.getContentPane().add(createUI());
            f.pack();
            f.setLocationRelativeTo(null);
            f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
            f.setVisible(true);
        });
    }

    static JComponent createUI() {
        String[][] rowData = new String[200][10];
        String[] columnNames = new String[10];
        for (int i = 0; i < 200; i++) {
            for (int j = 0; j < 10; j++) {
                if (i == 0) {
                    columnNames[j] = String.format("#%d", j);
                }
                rowData[i][j] = String.format("%d - %d", i, j);
            }
        }
        JTable t = new JTable(rowData, columnNames);
        JScrollPane sp = new JScrollPane(t);
        JScrollBar sb = sp.getVerticalScrollBar();
        JViewport vp = sp.getViewport();
        vp.addChangeListener((l) -> {
            if (!shouldCheck) {
                return;
            }
            if (sb.getValue() == sb.getMinimum()) {
                System.out.println("top");
            } else if (sb.getValue() + sb.getVisibleAmount() == sb.getMaximum()) {
                System.out.println("bottom");
            }
        });
        return sp;
    }
}