Java分页器封装

  1. 翻页器一:Paginator的封装
    • public final class PageList<T> implements Serializable {
      
          private static final long serialVersionUID = 7636400405542623379L;
      
          private List<T> datas;
      
          private Paginator paginator;
      
          public List<T> getDatas() {
              return datas;
          }
      
          public void setDatas(List<T> datas) {
              this.datas = datas;
          }
      
          public Paginator getPaginator() {
              return paginator;
          }
      
          public void setPaginator(Paginator paginator) {
              this.paginator = paginator;
          }
      }
      /**
       * 翻页器。
       * <p>
       * 此类对于在web页面上分页显示多项内容,计算页码和当前页的偏移量,十分方便实用。
       * </p>
       * <p>
       * 该类只需要知道总共有多少项,当前显示第几页,每页显示几项,就可以帮你计算出其它数据,而且保证所有计算都得出合理的值,不用担心页码超出边界之类的问题。
       * </p>
       * <p>
       * 使用方法如下:
       * <p/>
       * <p/>
       * <pre>
       * <![CDATA[
       *
       *   // 创建一个翻页器,可以在此指定每页显示几项,也可以以后再指定。
       *   // 如果没有指定,则使用默认值每页最多显示20项。
       *   Paginator pg = new Paginator();        // 或 new Paginator(itemsPerPage);
       *
       *   // 告诉我总共有几项。如果给的数字小于0,就看作0。
       *   pg.setItems(123);
       *
       *   // 如果不知道有几项,可以这样。
       *   pg.setItems(Paginator.UNKNOWN_ITEMS);
       *
       *   // 现在默认当前页是第一页,但你可以改变它。
       *   pg.setPage(3);                         // 这样当前页就是3了,不用担心页数会超过总页数。
       *
       *   // 现在你可以得到各种数据了。
       *   int currentPage = pg.getPage();        // 得到当前页
       *   int totalPages  = pg.getPages();       // 总共有几页
       *   int totalItems  = pg.getItems();       // 总共有几项
       *   int beginIndex  = pg.getBeginIndex();  // 得到当前页第一项的序号(从1开始数的)
       *   int endIndex    = pg.getEndIndex();    // 得到当前页最后一项的序号(也是从1开始数)
       *   int offset      = pg.getOffset();      // offset和length可以作为mysql查询语句
       *   int length      = pg.getLength();      //     的limit offset,length子句。
       *
       *   // 还可以做调整。
       *   setItemsPerPage(20);                   // 这样就每页显示20个了,当前页的值会自动调整,
       *                                          //     使新页和原来的页显示同样的项,这样用户不容易迷惑。
       *   setItem(33);                           // 这样可以把页码调整到显示第33号项(从0开始计数)的那一页
       *
       *   // 高级功能,开一个滑动窗口。我们经常要在web页面上显示一串的相邻页码,供用户选择。
       *   //        ____________________________________________________________
       *   // 例如:  <<     <       3     4    5    6    [7]    8    9    >    >>
       *   //        ^      ^                             ^               ^    ^
       *   //       第一页 前一页                       当前页          后一页 最后一页
       *   //
       *   // 以上例子就是一个大小为7的滑动窗口,当前页码被尽可能摆在中间,除非当前页位于开头或结尾。
       *   // 使用下面的调用,就可以得到指定大小的滑动窗口中的页码数组。
       *   int[] slider = pg.getSlider(7);
       *
       *   // 这样可以判断指定页码是否有效,或者是当前页。无效的页码在web页面上不需要链接。
       *   if (pg.isDisabledPage(slider[i])) {
       *       show = "page " + slider[i];
       *   } else {
       *       show = "<a href=#> page " + slider[i] + " </a>";
       *   }
       *
       *   // 可以直接打印出pg,用于调试程序。
       *   System.out.println(pg);
       *   log.debug(pg);
       *
       * ]]>
       * </pre>
       * <p/>
       * </p>
       *
       * @author YANGLiN
       */
      public class Paginator implements Serializable, Cloneable {
          /**
           * 每页默认的项数(9)。
           */
          public static final int DEFAULT_ITEMS_PER_PAGE = 9;
          /**
           * 滑动窗口默认的大小(7)。
           */
          public static final int DEFAULT_SLIDER_SIZE = 7;
          /**
           * 表示项数未知(<code>Integer.MAX_VALUE</code>)。
           */
          public static final int UNKNOWN_ITEMS = Integer.MAX_VALUE;
          private static final long serialVersionUID = 3688506614705230726L;
          // 状态量
          private int page; // 当前页码。(1-based)
          private int items; // 总共项数
          private int itemsPerPage; // 每页项数。
      
          /**
           * 创建一个分页器,初始项数为无限大<code>UNKNOWN_ITEMS</code>,默认每页显示<code>20</code>项。
           */
          public Paginator() {
              this(DEFAULT_ITEMS_PER_PAGE);
          }
      
          /**
           * 创建一个分页器,初始项数为无限大<code>UNKNOWN_ITEMS</code>,指定每页项数。
           *
           * @param itemsPerPage 每页项数。
           */
          public Paginator(int itemsPerPage) {
              this(itemsPerPage, UNKNOWN_ITEMS);
          }
      
          /**
           * 创建一个分页器,初始项数为无限大<code>UNKNOWN_ITEMS</code>,指定每页项数。
           *
           * @param itemsPerPage 每页项数。
           * @param items        总项数
           */
          public Paginator(int itemsPerPage, int items) {
              this.items = items >= 0 ? items : 0;
              this.itemsPerPage = itemsPerPage > 0 ? itemsPerPage : DEFAULT_ITEMS_PER_PAGE;
              this.page = calcPage(0);
          }
      
          /**
           * 取得总页数。
           *
           * @return 总页数
           */
          public int getPages() {
              return (int) Math.ceil((double) items / itemsPerPage);
          }
      
          /**
           * 取得当前页。
           *
           * @return 当前页
           */
          public int getPage() {
              return page;
          }
      
          /**
           * 设置并取得当前页。实际的当前页值被确保在正确的范围内。
           *
           * @param page 当前页
           * @return 设置后的当前页
           */
          public int setPage(int page) {
              return this.page = calcPage(page);
          }
      
          /**
           * 取得总项数。
           *
           * @return 总项数
           */
          public int getItems() {
              return items;
          }
      
          /**
           * 设置并取得总项数。如果指定的总项数小于0,则被看作0。自动调整当前页,确保当前页值在正确的范围内。
           *
           * @param items 总项数
           * @return 设置以后的总项数
           */
          public int setItems(int items) {
              this.items = items >= 0 ? items : 0;
              setPage(page);
              return this.items;
          }
      
          /**
           * 取得每页项数。
           *
           * @return 每页项数
           */
          public int getItemsPerPage() {
              return itemsPerPage;
          }
      
          /**
           * 设置并取得每页项数。如果指定的每页项数小于等于0,则使用默认值<code>DEFAULT_ITEMS_PER_PAGE</code>。
           * 并调整当前页使之在改变每页项数前后显示相同的项。
           *
           * @param itemsPerPage 每页项数
           * @return 设置后的每页项数
           */
          public int setItemsPerPage(int itemsPerPage) {
              int tmp = this.itemsPerPage;
      
              this.itemsPerPage = itemsPerPage > 0 ? itemsPerPage : DEFAULT_ITEMS_PER_PAGE;
      
              if (page > 0) {
                  setPage((int) ((double) (page - 1) * tmp / this.itemsPerPage) + 1);
              }
      
              return this.itemsPerPage;
          }
      
          /**
           * 取得当前页第一项在全部项中的偏移量 (0-based)。
           *
           * @return 偏移量
           */
          public int getOffset() {
              return page > 0 ? itemsPerPage * (page - 1) : 0;
          }
      
          /**
           * 取得当前页的长度,即当前页的实际项数。相当于 <code>endIndex() - beginIndex() + 1</code>
           *
           * @return 当前页的长度
           */
          public int getLength() {
              if (page > 0) {
                  return Math.min(itemsPerPage * page, items) - itemsPerPage * (page - 1);
              } else {
                  return 0;
              }
          }
      
          /**
           * 取得当前页显示的项的起始序号 (1-based)。
           *
           * @return 起始序号
           */
          public int getBeginIndex() {
              if (page > 0) {
                  return itemsPerPage * (page - 1) + 1;
              } else {
                  return 0;
              }
          }
      
          /**
           * 取得当前页显示的末项序号 (1-based)。
           *
           * @return 末项序号
           */
          public int getEndIndex() {
              if (page > 0) {
                  return Math.min(itemsPerPage * page, items);
              } else {
                  return 0;
              }
          }
      
          /**
           * 设置当前页,使之显示指定offset(0-based)的项。
           *
           * @param itemOffset 要显示的项的偏移量(0-based)
           * @return 指定项所在的页
           */
          public int setItem(int itemOffset) {
              return setPage(itemOffset / itemsPerPage + 1);
          }
      
          /**
           * 取得首页页码。
           *
           * @return 首页页码
           */
          public int getFirstPage() {
              return calcPage(1);
          }
      
          /**
           * 取得末页页码。
           *
           * @return 末页页码
           */
          public int getLastPage() {
              return calcPage(getPages());
          }
      
          /**
           * 取得前一页页码。
           *
           * @return 前一页页码
           */
          public int getPreviousPage() {
              return calcPage(page - 1);
          }
      
          /**
           * 取得前n页页码
           *
           * @param n 前n页
           * @return 前n页页码
           */
          public int getPreviousPage(int n) {
              return calcPage(page - n);
          }
      
          /**
           * 取得后一页页码。
           *
           * @return 后一页页码
           */
          public int getNextPage() {
              return calcPage(page + 1);
          }
      
          /**
           * 取得后n页页码。
           *
           * @param n 后n面
           * @return 后n页页码
           */
          public int getNextPage(int n) {
              return calcPage(page + n);
          }
      
          /**
           * 判断指定页码是否被禁止,也就是说指定页码超出了范围或等于当前页码。
           *
           * @param page 页码
           * @return boolean 是否为禁止的页码
           */
          public boolean isDisabledPage(int page) {
              return page < 1 || page > getPages() || page == this.page;
          }
      
          /**
           * 取得默认大小(<code>DEFAULT_SLIDER_SIZE</code>)的页码滑动窗口,并将当前页尽可能地放在滑动窗口的中间部位。参见
           * {@link #getSlider(int n)}。
           *
           * @return 包含页码的数组
           */
          public int[] getSlider() {
              return getSlider(DEFAULT_SLIDER_SIZE);
          }
      
          /**
           * 取得指定大小的页码滑动窗口,并将当前页尽可能地放在滑动窗口的中间部位。例如: 总共有13页,当前页是第5页,取得一个大小为5的滑动窗口,将包括
           * 3,4,5,6, 7这几个页码,第5页被放在中间。如果当前页是12,则返回页码为 9,10,11,12,13。
           *
           * @param width 滑动窗口大小
           * @return 包含页码的数组,如果指定滑动窗口大小小于1或总页数为0,则返回空数组。
           */
          public int[] getSlider(int width) {
              int pages = getPages();
      
              if (pages < 1 || width < 1) {
                  return new int[0];
              } else {
                  if (width > pages) {
                      width = pages;
                  }
      
                  int[] slider = new int[width];
                  int first = page - (width - 1) / 2;
      
                  if (first < 1) {
                      first = 1;
                  }
      
                  if (first + width - 1 > pages) {
                      first = pages - width + 1;
                  }
      
                  for (int i = 0; i < width; i++) {
                      slider[i] = first + i;
                  }
      
                  return slider;
              }
          }
      
          /**
           * 计算页数,但不改变当前页。
           *
           * @param page 页码
           * @return 返回正确的页码(保证不会出边界)
           */
          protected int calcPage(int page) {
              int pages = getPages();
      
              if (pages > 0) {
                  return page < 1 ? 1 : page > pages ? pages : page;
              }
      
              return 0;
          }
      
          /**
           * 创建复本。
           *
           * @return 复本
           */
          @Override
          public Object clone() {
              try {
                  return super.clone();
              } catch (CloneNotSupportedException e) {
                  return null; // 不可能发生
              }
          }
      
          /**
           * 转换成字符串表示。
           *
           * @return 字符串表示。
           */
          @Override
          public String toString() {
              StringBuffer sb = new StringBuffer("Paginator: page ");
      
              if (getPages() < 1) {
                  sb.append(getPage());
              } else {
                  int[] slider = getSlider();
      
                  for (int i = 0; i < slider.length; i++) {
                      if (isDisabledPage(slider[i])) {
                          sb.append('[').append(slider[i]).append(']');
                      } else {
                          sb.append(slider[i]);
                      }
      
                      if (i < slider.length - 1) {
                          sb.append('\t');
                      }
                  }
              }
      
              sb.append(" of ").append(getPages()).append(",\n");
              sb.append("    Showing items ")
                      .append(getBeginIndex())
                      .append(" to ")
                      .append(getEndIndex())
                      .append(" (total ")
                      .append(getItems())
                      .append(" items), ");
              sb.append("offset=").append(getOffset()).append(", length=").append(getLength());
      
              return sb.toString();
          }
      }
      

       

  2. 翻页器二:Page对象封装
    • public class Page {
          public static final int DEFAULT_PAGE_SIZE = 10;
          public static final int[] OPTIONAL_PAGE_SIZE = {20, 30, 50, 100};
          private int total = 0;
          private Integer pageSize = DEFAULT_PAGE_SIZE;
          private List<? extends Object> data = new ArrayList<Object>();
          private Integer pageIndex = 1;
          private boolean hasNext = false;
          private Integer pageIndexNew = 1;
      
          public Page() {
          }
      
          public Page(Integer pageIndex) {
              this.setPageIndex(pageIndex);
          }
      
          public int getTotal() {
              return total;
          }
      
          public void setTotal(int total) {
              this.total = total;
          }
      
          public int getPageSize() {
              return pageSize;
          }
      
          public void setPageSize(Integer pageSize) {
              if (null == pageSize || pageSize <= 0) {
                  this.pageSize = DEFAULT_PAGE_SIZE;
              }
              this.pageSize = pageSize;
          }
      
          public List<? extends Object> getData() {
              return data;
          }
      
          public void setData(List<? extends Object> data) {
              this.data = data;
          }
      
          public Integer getPageIndex() {
              return pageIndex > getPageTotal() ? getPageTotal() : pageIndex;
          }
      
          public void setPageIndex(Integer pageIndex) {
              if (pageIndex == null || pageIndex <= 0) {
                  pageIndex = 1;
              }
              this.pageIndex = pageIndex;
          }
      
          /**
           * start by 0
           *
           * @return
           */
          public int getStartIndex() {
              return total == 0 || pageIndex <= 1 ? 0 : (pageIndex - 1) * pageSize;
          }
      
          public int getEndIndex() {
              return getStartIndex() + pageSize;
          }
      
          public int getPageTotal() {
              return total % pageSize == 0 ? total / pageSize : total / pageSize + 1;
          }
      
          /**
           * 系统默认支持的不同pageSize的分页策略
           *
           * @return
           */
          public int[] getOptionalPageSize() {
              return OPTIONAL_PAGE_SIZE;
          }
      
          public boolean isHasNext() {
              return hasNext;
          }
      
          public void setHasNext(boolean hasNext) {
              this.hasNext = hasNext;
          }
      
          public Integer getPageIndexNew() {
              return pageIndexNew;
          }
      
          public void setPageIndexNew(Integer pageIndexNew) {
              this.pageIndexNew = pageIndexNew == null ? 1 : pageIndexNew;
          }
      
      
      }
      

       

 

 

 

转载于:https://my.oschina.net/sxshifeifei/blog/817416

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值