首先是分页内容的辅助类
package cn.com.timekey.drugmonitor.utils.db;
import java.util.Collections;
import java.util.List;
import org.hibernate.criterion.CriteriaSpecification;
/**
* 分页常用的bean类。<br>
* 里面包含搜索返回的List,查询条件DetachedCriteria及分页菜单用到的数据等。
*
* @author KennyLee E-mail:[email protected] 2008-10-25
* @param <T>
*/
public class PaginationSupport<T> {
// Default page size
public static final int PAGESIZE = 20;
public static final int MENU_SIZE = 7;
// total Rows
private int totalRowsAmount;
private int pageSize = PAGESIZE;
private int totalPages;
// current page number
private int currentPage = 1;
// next page number
private int nextPage;
// previous page number
private int previousPage;
// is has next page
private boolean hasNext;
// is has previous page
private boolean hasPrevious;
// current page start row number
private int pageStartRow = 0;
// current page end row number
private int pageEndRow;
private String[] pageMenuNum;
private int menuSize = MENU_SIZE;
// Pagination values
@SuppressWarnings("unchecked")
private List<T> items = Collections.EMPTY_LIST;
// select detachedCriteria
private CriteriaSpecification detachedCriteria;
public PaginationSupport() {
}
/**
* 构造函数。
*
* @param totalRows
* 总行数
* @param currentPage
* 当前页数
*/
public PaginationSupport(int totalRows, int currentPage) {
setPaginationSupport(totalRows, currentPage);
}
/**
* general 构造函数。
*
* @param totalRows
* 总行数
* @param currentPage
* 当前页数
* @param pageSize
* 每页显示数量。
*/
public PaginationSupport(int totalRows, int currentPage, int pageSize) {
this.pageSize = pageSize;
this.setPaginationSupport(totalRows, currentPage);
}
/**
* @param items
* @param totalCount
*/
public PaginationSupport(List<T> items, int totalCount) {
setPageSize(PAGESIZE);
setItems(items);
int currentPage = 1;
this.setPaginationSupport(totalCount, currentPage);
}
/**
* @param items
* @param totalCount
* @param startIndex
*/
public PaginationSupport(List<T> items, int totalCount, int startIndex) {
setPageSize(PAGESIZE);
setItems(items);
int currentPage = (startIndex / pageSize) + 1;
this.setPaginationSupport(totalCount, currentPage);
}
/**
* @param items
* 保存的目标List
* @param totalCount
* 查找的总行数
* @param pageSize
* 每页显示的行数
* @param startIndex
* 第几行开始
*
*/
public PaginationSupport(List<T> items, int totalCount, int pageSize,
int startIndex) {
setPageSize(pageSize);
setItems(items);
int currentPage = (startIndex / pageSize) + 1;
this.setPaginationSupport(totalCount, currentPage);
}
/**
* DetachedCriteria构造PS时的初始化方法。
*
* @param items
* 保存的目标List
* @param totalCount
* 查找的总行数
* @param pageSize
* 每页显示的行数
* @param startIndex
* 第几行开始
* @param detachedCriteria
*/
public PaginationSupport(List<T> items, int totalCount, int pageSize,
int startIndex, CriteriaSpecification detachedCriteria) {
setPageSize(pageSize);
setItems(items);
int currentPage = (startIndex / pageSize) + 1;
this.setPaginationSupport(totalCount, currentPage);
setDetachedCriteria(detachedCriteria);
}
/**
* <p>
* 替换items,重新构造PaginationSupport对象。
* </p>
*
* @param ps
* @param newItems
*/
public PaginationSupport(PaginationSupport<?> ps, List<T> newItems) {
this(newItems, ps.getTotalRowsAmount(), ps.getPageSize(), ps
.getPageStartRow());
}
public String[] getPageMenuNum() {
return pageMenuNum;
}
public void setPageMenuNum(String[] pageMenuNum) {
this.pageMenuNum = pageMenuNum;
}
public CriteriaSpecification getDetachedCriteria() {
return detachedCriteria;
}
public void setDetachedCriteria(CriteriaSpecification detachedCriteria) {
this.detachedCriteria = detachedCriteria;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public void setTotalPages(int totalPages) {
this.totalPages = totalPages;
}
public void setNextPage(int nextPage) {
this.nextPage = nextPage;
}
public void setPreviousPage(int previousPage) {
this.previousPage = previousPage;
}
public void setHasNext(boolean hasNext) {
this.hasNext = hasNext;
}
public void setHasPrevious(boolean hasPrevious) {
this.hasPrevious = hasPrevious;
}
public void setPageStartRow(int pageStartRow) {
this.pageStartRow = pageStartRow;
}
public List<T> getItems() {
return items;
}
public void setItems(List<T> items) {
this.items = items;
}
/**
* 分页导航按钮
*
* @param currentPage
* @return
*/
private String[] getPageMenuNums(int currentPage) {
String[] pageNums = null;
if (totalPages > menuSize) {// 总页数大于导航显示的页数
pageNums = new String[menuSize];
int lastMenuNum = totalPages - menuSize + 1;// 最后一列导航栏按钮
int beginMumNum = menuSize;
int x = menuSize - 1;// 导航显示系数
if ((currentPage < lastMenuNum) && (currentPage > beginMumNum)) {
for (int i = 0; i < menuSize; i++) {
pageNums[i] = String.valueOf(currentPage + i - x / 2);
}
} else if (currentPage > lastMenuNum) {
for (int i = 0; i < menuSize; i++) {
pageNums[i] = String.valueOf(lastMenuNum + i);
}
} else if (currentPage == lastMenuNum) {
if ((lastMenuNum - x / 2) < 1) {
lastMenuNum = x / 2 + 1;
}
for (int i = 0; i < menuSize; i++) {
pageNums[i] = String.valueOf(lastMenuNum + i - x / 2);
}
} else if (currentPage == beginMumNum) {
for (int i = 0; i < menuSize; i++) {
pageNums[i] = String.valueOf(1 + i + x / 2);
}
} else {
for (int i = 0; i < menuSize; i++) {
pageNums[i] = String.valueOf(1 + i);
}
}
} else {// 总页数小于等于导航显示的页数,直接显示。
pageNums = new String[totalPages];
// 分页数比总页数少
for (int i = 0; i < totalPages; i++) {
pageNums[i] = String.valueOf(i + 1);
}
}
return pageNums;
}
/**
* 设置总行数。
*
* @param rows
* 总行数。
*/
private void setTotalRowsAmount(int rows) {
if (rows < 0) {
totalRowsAmount = 0;
} else {
totalRowsAmount = rows;
}
if (totalRowsAmount % pageSize == 0) {
totalPages = totalRowsAmount / pageSize;
} else {
totalPages = totalRowsAmount / pageSize + 1;
}
}
/**
* 设置当前页数。
*
* @param curPage
*/
private void setCurrentPage(int curPage) {
if (curPage <= 0) {
currentPage = 1;
} else if (curPage > totalPages) {
currentPage = totalPages;
} else {
currentPage = curPage;
}
if (currentPage > 1) {
hasPrevious = true;
} else {
hasPrevious = false;
}
if (currentPage == totalPages) {
hasNext = false;
} else {
hasNext = true;
}
if (totalPages != 0) {
nextPage = currentPage + 1;
previousPage = currentPage - 1;
// 计算当前页开始行和结束行
pageStartRow = (currentPage - 1) * pageSize + 1;
// 记录索引从0开始
pageStartRow -= 1;
pageEndRow = pageStartRow + pageSize;
}
}
public void setPaginationSupport(int totalRows, int currentPage) {
// 获取总页码,通过对象总数还是每页多少行的关系
setTotalRowsAmount(totalRows);
setCurrentPage(currentPage);
String[] pageNums = getPageMenuNums(currentPage);
this.setPageMenuNum(pageNums);
}
public void setPageEndRow(int pageEndRow) {
this.pageEndRow = pageEndRow;
}
public int getCurrentPage() {
return currentPage;
}
public boolean isHasNext() {
return hasNext;
}
public boolean isHasPrevious() {
return hasPrevious;
}
public int getNextPage() {
return nextPage;
}
public int getPageSize() {
return pageSize;
}
public int getPreviousPage() {
return previousPage;
}
public int getTotalPages() {
return totalPages;
}
public int getTotalRowsAmount() {
return totalRowsAmount;
}
public int getPageStartRow() {
return pageStartRow;
}
public int getPageEndRow() {
return pageEndRow;
}
public String description() {
String description = "Total:" + this.getTotalRowsAmount() + " items "
+ this.getTotalPages() + " pages,Current page:"
+ this.currentPage + " Previous " + this.hasPrevious + " Next:"
+ this.hasNext + " start row:" + this.pageStartRow
+ " end row:" + this.pageEndRow;
return description;
}
public void init() {
// do some initialization work
}
public int getMenuSize() {
return menuSize;
}
public void setMenuSize(int menuSize) {
this.menuSize = menuSize;
}
}
查询页面内容后,使用 public PaginationSupport(List items, int totalCount, int startIndex) 构造方法来构造PaginationSupport实例。
然后我的action对应 PaginationSupport实例名字为 pageController(注意实现getPageController方法)。
初始化分页url,因为在很多情况下,分页是带查询参数,所以先把基本的url参数填上。参考如下:
<s:url value="asrd.do" id="pageUrl" escapeAmp="not">
<s:param name="beginStrDate" value="%{beginStrDate}"></s:param>
<s:param name="endStrDate" value="%{endStrDate}"></s:param>
<s:param name="timeCodeStr" value="%{timeCodeStr}"></s:param>
<s:param name="preTypeName" value="%{preTypeName}"></s:param>
<s:param name="firstDepId" value="%{firstDepId}"></s:param>
<s:param name="secondDepId" value="%{secondDepId}"></s:param>
</s:url>
这里的url不能使用action来构造链接,因为后面需要添加参数到url中,而用action的话会造成项目名重复的问题。所以退而求次的只能使用value构造链接,但就必须填上action的后缀了。
然后是分页按钮的标签jsp
<%@ page language="java" pageEncoding="UTF-8"
contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<!-- pagination menu begin by KennyLee 2011-6-2 -->
<s:if test="(pageController != null) and pageController.items.size gt 0">
<div id="pagination_info">[ 共 ${pageController.totalRowsAmount}
条记录 ] ${pageController.currentPage}/${pageController.totalPages}
页(每页显示 ${pageController.pageSize})</div>
<div class="pagination">
<s:if test="%{pageController.hasPrevious}">
<s:url id="previousPageUrl" value="%{pageUrl}">
<s:param name="toPage" value="%{pageController.previousPage}"></s:param>
</s:url>
<s:a href="%{previousPageUrl}"><Prev</s:a>
</s:if>
<s:else>
<span class="disabled"><Prev</span>
</s:else>
<s:iterator value="%{pageController.pageMenuNum}" status="status"
var="num">
<s:if test="#status.index eq 0">
<s:url id="firstPageUrl" value="%{pageUrl}">
<s:param name="toPage" value="1"></s:param>
</s:url>
<s:if test="%{#num eq 2}">
<s:a href="%{firstPageUrl}">1</s:a>
</s:if>
<s:if test="%{#num gt 2}">
<s:a href="%{firstPageUrl}">1</s:a>
<span>...</span>
</s:if>
</s:if>
<s:if test="#num eq pageController.currentPage">
<span class="current"> <s:property
value="%{pageController.currentPage}" /> </span>
</s:if>
<s:else>
<s:url id="listPageUrl" value="%{pageUrl}">
<s:param name="toPage" value="%{num}"></s:param>
</s:url>
<s:a href="%{listPageUrl}">
<s:property value="%{num}" />
</s:a>
</s:else>
<s:if test="(pageController.menuSize - 1) eq #status.index ">
<s:url id="lastPageUrl" value="%{pageUrl}">
<s:param name="toPage" value="%{pageController.totalPages}"></s:param>
</s:url>
<s:if test="(pageController.menuSize - 1) eq #num">
<s:a href="%{lastPageUrl}">
<s:property value="%{pageController.totalPages}" />
</s:a>
</s:if>
<s:if test="#num lt (pageController.totalPages-1)">
<span>...</span>
<s:a href="%{lastPageUrl}">
<s:property value="%{pageController.totalPages}" />
</s:a>
</s:if>
</s:if>
</s:iterator>
<s:if test="pageController.hasNext">
<s:url id="nextPageUrl" value="%{pageUrl}">
<s:param name="toPage" value="%{pageController.nextPage}"></s:param>
</s:url>
<s:a href="%{nextPageUrl}">Next></s:a>
</s:if>
<s:else>
<span class="disabled">Next></span>
</s:else>
</div>
<!-- pagination menu end -->
</s:if>
按钮样式
/******************** page start **************************/
div.pagination {
padding-right: 3px;
padding-left: 3px;
padding-bottom: 3px;
margin: 3px;
padding-top: 3px;
text-align: center;
}
div.pagination a {
border-right: #dedfde 1px solid;
padding-right: 6px;
background-position: 50% bottom;
border-top: #dedfde 1px solid;
padding-left: 6px;
padding-bottom: 2px;
border-left: #dedfde 1px solid;
color: #0061de;
margin-right: 3px;
padding-top: 2px;
border-bottom: #dedfde 1px solid;
text-decoration: none
}
div.pagination a:hover {
border-right: #000 1px solid;
border-top: #000 1px solid;
background-image: none;
border-left: #000 1px solid;
color: #fff;
border-bottom: #000 1px solid;
background-color: #0061de
}
div.pagination a:active {
border-right: #000 1px solid;
border-top: #000 1px solid;
background-image: none;
border-left: #000 1px solid;
color: #fff;
border-bottom: #000 1px solid;
background-color: #0061de
}
div.pagination span.current {
padding-right: 6px;
padding-left: 6px;
font-weight: bold;
padding-bottom: 2px;
color: #ff0084;
margin-right: 3px;
padding-top: 2px
}
div.pagination span.disabled {
padding-right: 6px;
padding-left: 6px;
padding-bottom: 2px;
color: #adaaad;
margin-right: 3px;
padding-top: 2px
}
div#pagination_info {
text-align: center;
}
/****end***/
最后效果如下: