swing之滚动条下拉加载数据

    在Swing作为界面开发的项目中会经常使用JScrollPane利用滚动条+JTable的形式来展现数据,有很多界面如微博、数据库工具等他们在滚动条下拉至底部时就自动将数据加载到界面中,利用JSCrollPane+JTable来模仿他们的实现。

    首先分析需求滚动条下拉,则需要为滚动条添加一个下拉的事件,通过JScrollPane的getVerticalScrollBar()或getHorizontalScrollBar()方法获取到竖向或横向滚动条,然后为滚动条添加鼠标的点击事件。

    然后分析滚动条下拉至底部,则需得到滚动条当前所在的位置和滚动条能够下拉到的最大位置,在JScrollBar中有两个方法:getMaximum(),getValue()。getMaximum():获取到滚动条的最大跨度值,如果JScrollPane中装的是JTable则该值就为JTable的行高乘上行数;getValue():获取滚动条当前所在位置的值。除了获取到这两个值还不够,还需通过JScrollBar通过getModel()获取到数据模型,通过该数据模型的getExtent()获取到模型的范围。

 

当getValue() + getExtent() =getMaximum()时,滚动条此时处于底部,这时就可以加载数据了。

通过以上的分析,接下来看一下具体的实现。为了在项目中更好的运用,这里封装了NTScrollPane类,该类继承了JScrollPane。为了增加程序的拓展性,这里的数据加载没有直接放在NTScrollPane中,而是定义了BaseDataLoader接口,子类继承该接口实现nextBatch()方法来加载下一批数据。类与类之间的关系如下图所示:

 

 

以下贴出实现源码:

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

 

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值