swing之滚动条下拉加载数据
2014-01-22 17:09
423 查看
在Swing作为界面开发的项目中会经常使用JScrollPane利用滚动条+JTable的形式来展现数据,有很多界面如微博、数据库工具等他们在滚动条下拉至底部时就自动将数据加载到界面中,利用JSCrollPane+JTable来模仿他们的实现。
首先分析需求滚动条下拉,则需要为滚动条添加一个下拉的事件,通过JScrollPane的getVerticalScrollBar()或getHorizontalScrollBar()方法获取到竖向或横向滚动条,然后为滚动条添加鼠标的点击事件。
然后分析滚动条下拉至底部,则需得到滚动条当前所在的位置和滚动条能够下拉到的最大位置,在JScrollBar中有两个方法:getMaximum(),getValue()。getMaximum():获取到滚动条的最大跨度值,如果JScrollPane中装的是JTable则该值就为JTable的行高乘上行数;getValue():获取滚动条当前所在位置的值。除了获取到这两个值还不够,还需通过JScrollBar通过getModel()获取到数据模型,通过该数据模型的getExtent()获取到模型的范围。
![](https://img-blog.csdn.net/20140122164013406)
[align=left] [/align]
当getValue() + getExtent() =getMaximum()时,滚动条此时处于底部,这时就可以加载数据了。
通过以上的分析,接下来看一下具体的实现。为了在项目中更好的运用,这里封装了NTScrollPane类,该类继承了JScrollPane。为了增加程序的拓展性,这里的数据加载没有直接放在NTScrollPane中,而是定义了BaseDataLoader接口,子类继承该接口实现nextBatch()方法来加载下一批数据。类与类之间的关系如下图所示:
![](https://img-blog.csdn.net/20140122163449062?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaGl5b2h1/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
[align=left] [/align]
以下贴出实现源码:
NTScrollPane类
BaseDataLoader接口
TableDataLoader类
TestDataLoader类
示例图片:
![](https://img-blog.csdn.net/20140122163340343?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaGl5b2h1/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](https://img-blog.csdn.net/20140122163406093?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaGl5b2h1/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
示例源码下载地址:http://download.csdn.net/detail/a78460750/6874617
首先分析需求滚动条下拉,则需要为滚动条添加一个下拉的事件,通过JScrollPane的getVerticalScrollBar()或getHorizontalScrollBar()方法获取到竖向或横向滚动条,然后为滚动条添加鼠标的点击事件。
然后分析滚动条下拉至底部,则需得到滚动条当前所在的位置和滚动条能够下拉到的最大位置,在JScrollBar中有两个方法:getMaximum(),getValue()。getMaximum():获取到滚动条的最大跨度值,如果JScrollPane中装的是JTable则该值就为JTable的行高乘上行数;getValue():获取滚动条当前所在位置的值。除了获取到这两个值还不够,还需通过JScrollBar通过getModel()获取到数据模型,通过该数据模型的getExtent()获取到模型的范围。
[align=left] [/align]
当getValue() + getExtent() =getMaximum()时,滚动条此时处于底部,这时就可以加载数据了。
通过以上的分析,接下来看一下具体的实现。为了在项目中更好的运用,这里封装了NTScrollPane类,该类继承了JScrollPane。为了增加程序的拓展性,这里的数据加载没有直接放在NTScrollPane中,而是定义了BaseDataLoader接口,子类继承该接口实现nextBatch()方法来加载下一批数据。类与类之间的关系如下图所示:
[align=left] [/align]
以下贴出实现源码:
NTScrollPane类
import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import javax.swing.JScrollBar; import javax.swing.JScrollPane; import javax.swing.SwingWorker; /** * * @author WZH */ public class NTScrollPane extends JScrollPane { private BaseDataLoader dataLoader; private boolean enable = true; public NTScrollPane() { this.getVerticalScrollBar().addMouseListener(new ScrollbarMouseAdapter()); } private class ScrollbarMouseAdapter extends MouseAdapter { @Override public void mouseReleased(MouseEvent e) { //判断是否可以使用,这里的布尔类型为了控制用户的频繁下拉操作 if (enable) { if (dataLoader != null) { JScrollBar bar = (JScrollBar) e.getSource(); int max = bar.getMaximum(); int extent = bar.getModel().getExtent(); int value = bar.getValue(); //判断滚动条是否拉到底部 if ((max - (value + extent)) < 10) { //设置鼠标在滚动面板上的光标为等待状态 NTScrollPane.this.setCursor(new java.awt.Cursor(java.awt.Cursor.WAIT_CURSOR)); new Task().execute(); } } } } } /** * 设置一个数据的加载器 * @param dataLoader */ public void setDataLoader(BaseDataLoader dataLoader) { this.dataLoader = dataLoader; } /** * 任务类,用来加载数据 */ private class Task extends SwingWorker<Void, Void> { @Override protected Void doInBackground() throws Exception { enable = false; Thread.sleep(2000);//增强加载效果,停留两秒 dataLoader.nextBatch(); return null; } @Override protected void done() { //设置滚动面板设置上鼠标设置为默认光标 NTScrollPane.this.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR)); enable = true; } } }
BaseDataLoader接口
/** * 接口 * @author WZH */ public interface BaseDataLoader { void nextBatch(); }
TableDataLoader类
import javax.swing.table.DefaultTableModel; /** * * @author WZH */ public abstract class TableDataLoader implements BaseDataLoader { private DefaultTableModel model;//表模型 private int page;//从第几页开始 private int number;//每次加载的数量 /** * 构造方法,只需传入表模型参数,page为0,number为50 * @param model */ TableDataLoader(DefaultTableModel model) { this(model, 0, 50); } /** * 构造方法 * @param model 表模型 * @param page 从第几页开始的索引 * @param number 每次加载的数量 */ TableDataLoader(DefaultTableModel model, int page, int number) { this.model = model; this.page = page; this.number = number; } /** * 初始化表数据 */ abstract void initTableData(); @Override public void nextBatch() { page ++; } /** * 获取表模型 * @return 表模型 */ public DefaultTableModel getModel() { return model; } /** * 获取从第几页加载 * @return 索引 */ public int getPage() { return page; } /** * 获取每次加载数量 * @return 加载数量 */ public int getNumber() { return number; } }
TestDataLoader类
import javax.swing.table.DefaultTableModel; /** * * @author WZH */ public class TestDataLoader extends TableDataLoader { TestDataLoader(DefaultTableModel model) { this(model, 0, 50); } TestDataLoader(DefaultTableModel model, int page, int number) { super(model, page, number); } @Override public void initTableData() { this.nextBatch(); } @Override public void nextBatch() { DefaultTableModel model = this.getModel(); int page = this.getPage(); int number = this.getNumber(); int rowcount = model.getRowCount(); //模拟数据,根据具体需求换成自己想要加载的数据,如从数据库中分页获取数据 String[] t = new String[number]; for(int i=0; i<number; i++) { t[i] = "第" + (page * number + i) + "个数据"; } for (String value : t) { model.insertRow(rowcount, new String[]{value}); rowcount++; } super.nextBatch(); } }
示例图片:
示例源码下载地址:http://download.csdn.net/detail/a78460750/6874617
相关文章推荐
- 下拉滚动条时自动加载所需数据
- 页面滚动动态加载数据,页面下拉自动加载内容 ,滚动条滚动到最底端加载数据
- jQuery实现模仿微博下拉滚动条加载数据效果
- jQuery实现模仿微博下拉滚动条加载数据效果
- PullToRefresh 上拉刷新,下拉加载数据 框架的简单使用
- WP8_当滚动到滚动条的70%时,自动加载数据效果实现
- 拉动滚动条加载数据
- Windows Phone开发经验谈(18)-总结两种滚动条到底部加载数据的方法
- PullToRefresh 上拉刷新,下拉加载网络数据 ListView
- 判断页面加载后是否所有的下拉框都有数据
- 对easyui datagrid 进行扩展拉动滚动条到底部自动加载数据《二》
- Datagridview中的数据很多,加载完数据后滚动条自动到最下边,如何解决?
- jquery combobox下拉及异步加载数据
- multiple select 下拉到滚动条底部 异步加载 onscroll
- Ajax 下拉加载数据
- 拉动滚动条加载数据的jquery代码
- jquery滚动条加载数据
- flex的tree动态加载大量数据与滚动条相关问题探讨
- ASP.NET仿新浪微博下拉加载更多数据瀑布流效果