我想知道是否有办法知道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());
}
});
两种替代实现(部分对克列奥帕特拉做出反应)
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 个值:最小值、最大值、值和范围。 value
是滚动手柄本身的顶部,extent
是滚动手柄的有效长度。 value
永远不会等于maximum
,除非滚动手柄的长度为 0。为了补偿,我们必须通过减去滚动手柄的长度来调整我们正在比较的值以获得有效最大值。
这里记录了这种效果,这误导性地使它听起来像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()