如何知道JScrollBar是否已经到达JScrollPane的底部?
我想知道是否有办法知道JScrollBar
(在我的情况下是垂直的)何时到达包含JScrollPane
的底部。
起初我虽然在滚动条上使用了AdjustmentListener
,但我不知道如何解释JScrollBar
的value
属性。 此外,我不确定正确理解maximum
代表什么,如果我可以使用该值来获取我需要的信息。
编辑 :
scrollPane.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() { @Override public void adjustmentValueChanged(AdjustmentEvent ae) { System.out.println("Value: " + scrollPane.getVerticalScrollBar().getValue() + " Max: " + scrollPane.getVerticalScrollBar().getMaximum()); } }
您必须将滚动条的范围添加到计算中。 我在下面的示例中将代码添加到您的代码中。
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()); } });
两种替代实施(部分对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()); } });
或者通过模型
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几乎得到了正确答案。
尝试使用scrollBar.getValue() == scrollBar.getMaximum() - scrollBar.getVisibleAmount()
。
要了解为什么需要getVisibleAmount()
调用,首先必须了解JScrollBars的工作原理。 JScrollBar有4个值:minimum,maximum,value和extent。 value
是滚动句柄本身的顶部, extent
是滚动句柄的有效长度。 除非滚动句柄的长度为0,否则value
永远不会等于maximum
。为了补偿,我们必须通过减去滚动句柄的长度来调整我们所比较的值,以获得有效的最大值。
这里记录了这种效果,误导性地使它听起来像getMaximum()
调整值应该如此,但仔细观察JScrollBar的实现表明getMaximum()
实际上给出了真正的最大值,而不是有效最大值。
通过使用JScrollPane的视口,您可以计算视口是否正在查看组件的结尾。
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()