`
oojdon
  • 浏览: 39727 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

我写分页类

阅读更多

分页,以JavaEye为例子,长得像这两幅图:



 

 

长了就用...隐藏一部分,我把这一串数字提取出来做一个数据容器,取名分页条PageBar,里面就是一串数字,比如存放上面图片中的1,2,3 545,546,...用-1代替,得到一个类

 

public class CssPageBar {

	private int [] linkNums;

	public int[] getLinkNums() {
		return linkNums;
	}

	public void setLinkNums(int[] linkNums) {
		this.linkNums = linkNums;
	}
	
}

 

分页只是滚动导航数据记录,但是用户真正想看到的记录内容必须用一个对象来表示,取名Page,泛化一下,运行时装入各种类型的待显示数据,同时把判断当前这个Page是否有下页和上页的责任付给它,因为各个Page在数据记录中的位置是可以确定的,所以这个很好计算,于是Page类代码如下

 

public class Page<T> {

	private int pageNo = 1;// 第几页

	private int pageSize = 3;// 每页显示的记录数

	private int totalCount;// 数据中记录的总条数

	private List<T> result = new ArrayList<T>();// 每页需要显示的真实数据记录

	private String orderBy = null;

	private boolean asc = true;

	private Map queryParams = new HashMap();// 封装页面的查询参数

	public Page() {

	}

	public Page(int pageNo) {
		this.pageNo = pageNo;
	}

	// 每页的第一条记录在结果集中的位置
	public int getPageFirst() {
		return ((pageNo - 1) * pageSize);
	}

	// 总页数,这个是根据totalcount和pageSize计算的
	public int getTotalPages() {
		if (totalCount == 0)
			return 0;

		int count = totalCount / pageSize;
		if (totalCount % pageSize > 0) {
			count++;
		}
		return count;
	}

	/**
	 * 是否还有下一页.
	 */
	public boolean isHasNext() {
		return (pageNo + 1 <= getTotalPages());
	}

	/**
	 * 返回下页的页号,序号从1开始.
	 */
	public int getNextPage() {
		if (isHasNext())
			return pageNo + 1;
		else
			return pageNo;
	}

	/**
	 * 是否还有上一页.
	 */
	public boolean isHasPre() {
		return (pageNo - 1 >= 1);
	}

	/**
	 * 返回上页的页号,序号从1开始.
	 */
	public int getPrePage() {
		if (isHasPre())
			return pageNo - 1;
		else
			return pageNo;
	}

	/**
	 * 设置查询参数
	 */
	public void setQueryParam(String paramName, String paramValue) {
		this.queryParams.put(paramName, paramValue);
	}

	/**
	 * 
	 * 多条件查询的URL参数
	 */
	public String getUrlParam() {
		StringBuilder urlParam = new StringBuilder();
		Map params = this.getQueryParams();
		Iterator<String> keys = params.keySet().iterator();
		if (params != null && keys.hasNext()) {
			String key = keys.next();
			urlParam.append(key).append("=").append(params.get(key));
			while (keys.hasNext()) {
				key = keys.next();
				urlParam.append("&").append(key).append("=").append(
						params.get(key));
			}
		}
		return urlParam.toString();
	}

	/**
	 * 单个的排序字段.
	 */
	public String getOrderBy() {
		return orderBy;
	}

	public void setOrderBy(String orderBy) {
		this.orderBy = orderBy;
	}

	public boolean isOrderBySetted() {
		return this.orderBy != null;
	}

	/**
	 * 是否升序,默认为true.
	 */
	public boolean isAsc() {
		return asc;
	}

	public void setAsc(boolean asc) {
		this.asc = asc;
	}

	public int getPageNo() {
		return pageNo;
	}

	public void setPageNo(int pageNo) {
		this.pageNo = pageNo;
	}

	public int getPageSize() {
		return pageSize;
	}

	public void setPageSize(int pageSize) {
		this.pageSize = pageSize;
	}

	public int getTotalCount() {
		return totalCount;
	}

	public void setTotalCount(int totalCount) {
		this.totalCount = totalCount;
	}

	public List<T> getResult() {
		return result;
	}

	public void setResult(List<T> result) {
		this.result = result;
	}

	public Map getQueryParams() {
		return queryParams;
	}

}
 

 

把这两个对象放到页面的渲染上下文中就可以实现分页了,因为后台只提供数据,前端可用各种CSS来控制显示样式,改名刚才那个PageBar为CssPageBar,这个对象是通过分析Page对象得到的,所以另外需要一个工具类来做这个事情,代码如下

 

public class PageProcessor {

	public static int THRESHOLDFORELLIPSIS = 5;// 预设值,系统默认为5

	public <T> CssPageBar process(Page<T> page) {
		int totalPage = page.getTotalPages();
		int currentPage = page.getPageNo();
		CssPageBar cssPageBar = new CssPageBar();
		cssPageBar.setLinkNums(this.linkNums(totalPage, currentPage));
		return cssPageBar;
	}

	private int[] linkNums(int totalPage, int currentPage) {
		int[] pre = new int[0]; // 当前页的前组,包含当前页
		int[] next = new int[0];// 当前页的后组,不包含当前页

		if (totalPage > 0) {
			// 处理前组
			if (currentPage <= THRESHOLDFORELLIPSIS) {
				pre = new int[currentPage];
				for (int i = 0; i < pre.length; i++) {
					pre[i] = i + 1;
				}
			} else if (currentPage == totalPage) {
				pre = new int[THRESHOLDFORELLIPSIS + 1];
				pre[0] = 1;
				pre[1] = 2;
				pre[2] = -1;
				pre[3] = currentPage - 2;
				pre[4] = currentPage - 1;
				pre[5] = currentPage;
			} else {
				pre = new int[THRESHOLDFORELLIPSIS];
				pre[0] = 1;
				pre[1] = 2;
				pre[2] = -1;
				pre[3] = currentPage - 1;
				pre[4] = currentPage;
			}
			// 处理后组
			if ((totalPage - currentPage) <= (THRESHOLDFORELLIPSIS - 1)) {
				next = new int[totalPage - currentPage];
				for (int i = 0; i < next.length; i++) {
					next[i] = currentPage + i + 1;
				}
			} else if (currentPage == 1) {
				next = new int[THRESHOLDFORELLIPSIS];
				next[0] = 2;
				next[1] = 3;
				next[2] = -1;
				next[3] = totalPage - 1;
				next[4] = totalPage;
			} else {
				next = new int[THRESHOLDFORELLIPSIS - 1];
				next[0] = currentPage + 1;
				next[1] = -1;
				next[2] = totalPage - 1;
				next[3] = totalPage;
			}
		}

		// 合并
		int[] linkNums = new int[pre.length + next.length];

		int index = 0;
		for (int num : pre) {
			linkNums[index++] = num;
		}
		for (int num : next) {
			linkNums[index++] = num;
		}

		return linkNums;
	}

}
 

前端显示,可用jsp或者模板引擎,用CommonTemplate的代码如下

 

<div id="pagination" align="center" class="pagination">
${page.totalCount}条记录,每页显示${page.pageSize}条记录,一共${page.totalPages}页:
$if{page.hasPre == true}<a href="/jdonmvcdemo?page.pageNo=${page.prePage}">上一页</a>$end
$if{page.hasPre != true}<span class=disabled >上一页</span>$end

$for{number : cssPageBar.linkNums}
$if{number == -1}<span class="disabled">...</span>$end
$if{number == page.pageNo}<span class="current">${page.pageNo}</span>$end
$if{number != -1 && number != page.pageNo}<a href="/jdonmvcdemo?page.pageNo=${number}"/>${number}</a>$end
$end

$if{page.hasNext == true}<a href="/jdonmvcdemo?page.pageNo=${page.nextPage}">下一页</a>$end
$if{page.hasNext != true}<span class=disabled >下一页</span>$end
</div>

 用Jsp的代码如下

 

<div id="pagination" align="center" class="pagination">
${page.totalCount}条记录,每页显示${page.pageSize}条记录,一共${page.totalPages}页:
<c:if test="${page.hasPre}"><a href="/jdonmvcdemo?page.pageNo=${page.prePage}">上一页</a></c:if>
<c:if test="${!page.hasPre}"><span class=disabled >上一页</span></c:if>

<c:forEach var="number" items="${cssPageBar.linkNums}">
<c:if test="${number == -1}"><span class="disabled">...</span></c:if>
<c:if test="${number == page.pageNo}"><span class="current">${page.pageNo}</span></c:if>
<c:if test="${number != -1 && number != page.pageNo}"><a href="/jdonmvcdemo?page.pageNo=${number}"/>${number}</a></c:if>
</c:forEach>

<c:if test="${page.hasNext}"><a href="/jdonmvcdemo?page.pageNo=${page.nextPage}">下一页</a></c:if>
<c:if test="${!page.hasNext}"><span class=disabled >下一页</span></c:if>
</div>
 

用Velocity的代码如下

 

<div id="pagination" align="center" class="pagination">
$page.totalCount条记录,每页显示$page.pageSize条记录,一共$page.totalPages页:
#if($page.hasPre == true)<a href="/jdonmvcdemo?page.pageNo=$page.prePage">上一页</a>#end
#if($page.hasPre != true)<span class=disabled >上一页</span>#end

#foreach($number in $cssPageBar.linkNums)
#if($number == -1)<span class="disabled">...</span>#end
#if($number == $page.pageNo)<span class="current">$page.pageNo</span>#end
#if($number != -1 && $number != $page.pageNo)<a href="/jdonmvcdemo?page.pageNo=$number"/>$number</a>#end
#end

#if($page.hasNext == true)<a href="/jdonmvcdemo?page.pageNo=$page.nextPage">下一页</a>#end
#if($page.hasNext != true)<span class=disabled >下一页</span>#end
</div>

 

 

另外附上前端的CSS,你可以用你的想象力,或者找美工做这个样式,我们项目就是美工给我做

 

DIV.pagination {
padding:3px;
margin:3px;
font-size: 10px;
font-weight: bold;
font-family: Verdana;
}

DIV.pagination a {
padding: 2px 5px 2px 5px;
margin-right: 2px;
border: 1px solid #9aafe5;
text-decoration: none; 
color: #2e6ab1;
}
DIV.pagination a:hover, .pagination a:active {
border: 1px solid #dd6900;
color: #000;
background-color: lightyellow;
text-decoration: none;
}
DIV.pagination .current {
padding: 2px 5px 2px 5px;
margin-right: 2px;
border: 1px solid navy;
font-weight: bold;
background-color: #2e6ab1;
color: #FFF;
}
DIV.pagination .disabled {
padding: 2px 5px 2px 5px;
margin-right: 2px;
border: 1px solid #929292;
color: #929292;
}
 

我再Jdon也贴过代码,链接如下http://www.jdon.com/jivejdon/thread/36398

 

顺便提一下Jdon框架中的分页实现,Jdon框架有CQRS的味道,banq在查询端抽象了一个ModelListAction,用户继承这个类然后重写两个方法以提供数据,框架会在运行时先从缓存里读取数据,然后用一个分页标签显示分页条。

  • 大小: 5.1 KB
  • 大小: 5.4 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics