0
回答
让 JScrollbar 滚动条自动滚动到底端
华为云4核8G,高性能云服务器,免费试用   

由于项目需要,自定义了一个面板,JScrollpane下填充一个JTable表格,表格的单元格采用自定义的渲染器 TableTextAreaCellRenderer(用JTextArea代替JLabel,后者其实就是默认的 DefaultCellRenderer)。按照要求,面板填完内容之后,滚动条自动滚动到最低端。貌似是个简单的问题,考虑过的实现方式如下:

JScrollBar scrollBar = this.jScrollPane1.getVerticalScrollBar();
scrollBar.setValue(scrollBar.getMaxmium());

实际效果很不理想,特别是当单元格内容行数很多时。所以又用了变通的第二种方法,让最后一行的单元格去获取焦点,自然也就实现了滚动条到下面

if (noteTable.getRowCount() != 0) {
            int rowCount = noteTable.getRowCount();
            noteTable.getSelectionModel().setSelectionInterval(rowCount - 1, rowCount - 1);//选定该单元格,可有可无
            Rectangle rect = noteTable.getCellRect(rowCount - 1, 0, false);
            noteTable.scrollRectToVisible(rect);

}

测试时和第一种方法的结果类似,所以也放弃了,接着有了第三种方法:

JScrollBar scrollBar = this.jScrollPane1.getVerticalScrollBar();

scrollBar.setValue(scrollBar.getModel().getMaximum() - scrollBar.getModel().getExtent());

直接用还是会有问题,JScrollPane构建后会自动调整界面,填充内容之后立即调用上面的代码会发现 scrollBar.getModel().getMaximum() 和 scrollBar.getModel().getExtent()仍然为零或者不稳定, 也就意味着自动调整尚未结束,结果就不会是value被设置到最大值或者说滚动条置底。解决的办法就是添加侦听事件,当监听到自动调整完毕,调用以上方法。但此时又遇到另一个问题,自动调整结束的标志是什么,该监听哪种事件判断哪个属性的改变,我的方法是:

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

            public void adjustmentValueChanged(AdjustmentEvent evt) {
                if(evt.getAdjustmentType() == AdjustmentEvent.TRACK && isNeedBottom <= 3) {                   jScrollPane1.getVerticalScrollBar().setValue(jScrollPane1.getVerticalScrollBar().getModel().getMaximum() - jScrollPane1.getVerticalScrollBar().getModel().getExtent());
                    isNeedBottom++;
                }
            }

});

红色部分意味着正在进行自动调整,蓝色部分的意思是进行三次调整(原因是自动调整并不是进行一次,采用调试-局部变量查看可以知道,多数情况两次,最多三次),isNeedBottom 是定义的全局整型变量,需要滚动条自动滚动到底端时将其设置为0即可。经过测试,按这种方法最终达到了要求。

回过头来想想,监听状态是变通的方法,自己并没有找到自动调整反映在哪个属性上,如果可以监听该属性的改变,方法更明确也更简单。
举报
华宰
发帖于7年前 0回/2K+阅
顶部