扔掉T5复杂的Grid组件,打造自己灵活的支持分页排序组件。

Grid算是比较T5中较复杂的一个组件,我也有篇介绍Grid怎么使用的文章。[url]http://www.iteye.com/topic/114754[/url] 但是如果我们平时需要些比较灵活的布局。 Grid组件用起来就比较别扭了。

下面我介绍下使用Loop组件实现一个灵活但是又不缺乏分页,排序功能的Grid组件的实现。

首先我们全局看下页面上是要怎样写的。

        <table>
<tr>
<td><a t:type="OrderColumn" orderProperty="country" paging="paging">Country</a> </td>
<td><a t:type="OrderColumn" orderProperty="language" paging="paging">Language</a> </td>
</tr>
<tr t:type="Loop" source="items" value="item">
<td>${item.country}</td>
<td>${item.language}</td>
</tr>
<tr>
<td colspan="2"><div t:type="PageNavigation" paging="paging" useAll="false"></div></td>
</tr>
</table>


是不是比较简单。 你可以单独输出Table的头部和body部分。 这里使用了2个组件一个OrderColumn,一个是PageNavigation。 这两个组件公用了一个paging对象, 这个paging对象其实提供了对分页,和当前排序字段的支持。 下面看看page class的内容。

package com.iteye.com.dengyin000.tapestry.quickstart.pages;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import org.apache.tapestry.annotations.Persist;

import com.iteye.com.dengyin000.tapestry.quickstart.utils.Paging;

/**
* Start page of application quickstart.
*/
public class Start
{
@Persist("session")
private Paging paging;

private Locale item;

public Locale getItem() {
return item;
}

public Date getCurrentTime()
{
return new Date();
}

public Locale[] getAvailableLocales(){
return Locale.getAvailableLocales();
}

public void pageLoaded(){
if (paging == null){
paging = new Paging("country");
}
}

public List<Locale> getItems(){
Locale[] availableLocales = Locale.getAvailableLocales();
List<Locale> list = Arrays.asList(availableLocales);
paging.setItemCount(list.size());
return list.subList(paging.getFirstResult(), paging.getFirstResult() + paging.getMaxResults());
}

public Paging getPaging() {
return paging;
}

public void setPaging(Paging paging) {
this.paging = paging;
}

public void setItem(Locale item) {
this.item = item;
}
}



这里我们把paging对象保存在了session里。 然后绑定到OrderColumn和PageNavigation组件中。 请注意getItems方法。 这个是获得你要显示的数据。 这里你要先得到所有的数据的总数然后调用setItemCount方法, 然后你要通过paging中的firstResult maxResult orderProperty order(desc,ase)去获取你要显示的数据。 下面看看paging对象。

package com.iteye.com.dengyin000.tapestry.quickstart.utils;

import java.io.Serializable;
import java.util.List;

public class Paging implements Serializable {

private static final long serialVersionUID = 4260574632101852340L;

public static int ROWS_PER_PAGE = 15;

public static int ALL = -1;

private int firstResult = 0;

private int maxResults = ROWS_PER_PAGE;

/**
* One or more property names separated by comma (,). They are later used in
* ORDER BY clause.
*/
private String orderProperties;

private boolean orderDescending = false;

private int pageNo = 0;

private long itemCount = 0;

private String alias = null;

protected boolean recalculateFirst = false; // enabled by setPageNo or
// setItemCount

private transient List results;

public Paging(String orderColumn) {
setOrderProperties(orderColumn);
}

public Paging(String orderColumn, boolean orderDescending) {
setOrderProperties(orderColumn);
setOrderDescending(orderDescending);
}

public Paging(String orderColumn, int pageNo) {
setOrderProperties(orderColumn);
setPageNo(pageNo);
}

public Paging(int firstResult, int maxResults, String orderColumn,
boolean orderDescending) {
this(firstResult, maxResults, orderColumn, null, orderDescending);
}

public Paging(int firstResult, int maxResults, String orderColumn,
String alias, boolean orderDescending) {
setFirstResult(firstResult);
setMaxResults(maxResults);
setOrderProperties(orderColumn);
setOrderDescending(orderDescending);
setAlias(alias);
}

public boolean isAll() {
return pageNo == ALL;
}

public int getFirstResult() {
if (this.recalculateFirst == true) {
if (pageNo != ALL) {
if (pageNo < 0) {
pageNo = 0;
}
firstResult = pageNo * maxResults;
if (firstResult >= itemCount) {
firstResult = pageNo = 0;
}
} else {
firstResult = 0;
}
this.recalculateFirst = false;
}
return firstResult;
}

public void changeSortColumn(String sortColumn) {
if (sortColumn != null && sortColumn.equals(getOrderProperties())) {
setOrderDescending(isOrderDescending() == true ? false : true); // change
// order
// desc
} else {
setOrderDescending(false); // set ascending order
setOrderProperties(sortColumn);
}
}

public void setFirstResult(int firstResult) {
this.firstResult = firstResult;
}

public int getMaxResults() {
return maxResults;
}

public void setMaxResults(int maxResults) {
this.maxResults = maxResults;
}

public String getOrderProperties() {
return orderProperties;
}

public void setOrderProperties(String sortColumn) {
this.orderProperties = sortColumn;
}

public boolean isOrderDescending() {
return orderDescending;
}

public void setOrderDescending(boolean sortOrder) {
this.orderDescending = sortOrder;
}

public long getItemCount() {
return itemCount;
}

public void setItemCount(long itemCount) {
this.itemCount = itemCount;
this.recalculateFirst = true;
}

public int getPageNo() {
return pageNo;
}

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

public String getAlias() {
return alias;
}

public void setAlias(String alias) {
this.alias = alias;
}

public void setResults(List results) {
this.results = results;
}

public List getResults() {
return results;
}

/**
* apply order properties to the query string.
* @param query
* @param pas
* @return
*/
public static String buildOrderBy(String query, Paging pas) {
//FIXME
if (pas != null && pas.getOrderProperties() != null) {
StringBuffer orderBy = new StringBuffer();
/** Oracle
int groupindex = query.toLowerCase().indexOf(" group ");
if(groupindex>0){
int i = query.toLowerCase().indexOf(" by ",groupindex+1);
if(i>groupindex && (i-groupindex)<12)return query;
}
**/
int posOrder = query.toLowerCase().indexOf(" order ");
if (posOrder > 0) {
int posBy = query.toLowerCase().indexOf(" by ", posOrder - 1);
if (posBy >= 0) {
orderBy.append(query.substring(0, posOrder));
} else
orderBy.append(new String(query));
} else {
orderBy.append(new String(query));
}

orderBy.append(" order by ");
String[] orderCols = pas.getOrderProperties().split(",");
for (int i = 0; i < orderCols.length; i++) {
if (i > 0) {
orderBy.append(", ");
}
if (pas.getAlias() != null) {
orderBy.append(pas.getAlias() + ".");
}

orderBy.append(orderCols[i]);

if (pas.isOrderDescending()) {
orderBy.append(" desc");
}
}
return orderBy.toString();
}
return query;

}

/**
* 'from User' or 'select name from User' will be changed to
* 'select count(*) from User'
* replace select fields with count(*)
* @param queryString
* @return
*/
public static String buildItemCount(String queryString) {
int posOfFrom = queryString.toLowerCase().indexOf("from ");
return "select count(*) " + queryString.substring(posOfFrom);
}
}


ok, 下面贴下OrderColumn, PageNavigation的代码

OrderColumn.tml

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<span xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
<a t:type="ActionLink" t:id="changeOrderLink" t:context="orderProperty">
<t:body/><img src="${icon}" class="t-sort-icon" alt="${iconLabel}"/>
</a>
</span>


OrderColumn.java
package com.iteye.com.dengyin000.tapestry.quickstart.components;

import org.apache.tapestry.Asset;
import org.apache.tapestry.annotations.Parameter;
import org.apache.tapestry.annotations.Path;
import org.apache.tapestry.ioc.annotations.Inject;

import com.iteye.com.dengyin000.tapestry.quickstart.utils.Paging;

public class OrderColumn {

@Parameter(required=true, defaultPrefix="literal")
private String orderProperty;

@Parameter(required=true)
private Paging paging;

@Inject
@Path("sort-asc.png")
private Asset _ascendingAsset;

@Inject
@Path("sort-desc.png")
private Asset _descendingAsset;

@Inject
@Path("sortable.png")
private Asset _sortableAsset;

public String getOrderProperty() {
return orderProperty;
}

public void setOrderProperty(String orderProperty) {
this.orderProperty = orderProperty;
}

public Paging getPaging() {
return paging;
}

public void setPaging(Paging paging) {
this.paging = paging;
}

public void onActionFromChangeOrderLink(String orderProperty){
paging.changeSortColumn(orderProperty);
}

public Asset getIcon(){
if (isActiveSortColumn()) {
return getPaging().isOrderDescending() ? _descendingAsset : _ascendingAsset;
}

return _sortableAsset;
}

private boolean isActiveSortColumn() {
return orderProperty.equals(getPaging().getOrderProperties());
}

public String getIconLabel(){
String key = isActiveSortColumn() ? ( getPaging().isOrderDescending() ? "descending": "ascending")
: "sortable";

return key;
}
}



PageNavigation.tml

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<span t:type="If" t:test="navigationDisplayed" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
<table border="0">
<tr>
<td> </td>
<td class="navigation">
<span t:type="If" t:test="notUnderAllStatus">
<a t:type="ActionLink" t:id="first" t:context="first" t:disabled="firstDisabled">|<<</a>
 
<a t:type="ActionLink" t:id="previous" t:context="previous" t:disabled="previousDisabled"><<</a>
 
Page ${currentPage} Of ${pageCount}
<a t:type="ActionLink" t:id="next" t:context="next" t:disabled="nextDisabled">>></a>
 
<a t:type="ActionLink" t:id="last" t:context="last" t:disabled="lastDisabled">>>|</a>
 
<span t:type="If" t:test="useAll">
<a t:type="ActionLink" t:context="all" t:disabled="allDisabled">All</a>
<t:parameter name="else">
<a t:type="ActionLink" t:id="pageStatus" t:disabled="prop:notUnderAllStatus">View Paginated</a>
</t:parameter>
</span>
</span>
</td>
</tr>
</table>
</span>


PageNavigation.java

package
com.iteye.com.dengyin000.tapestry.quickstart.components;

import org.apache.tapestry.annotations.OnEvent;
import org.apache.tapestry.annotations.Parameter;
import org.apache.tapestry.annotations.Persist;

import com.iteye.com.dengyin000.tapestry.quickstart.utils.Paging;

public class PageNavigation {

@Persist
private boolean underAllStatus;
@Parameter(required=true)
private Paging paging;

private Integer num;

@Parameter
private boolean useAll;

public boolean isUseAll() {
return useAll;
}

public void setUseAll(boolean useAll) {
this.useAll = useAll;
}

public boolean isUnderAllStatus() {
return underAllStatus;
}

public boolean getNotUnderAllStatus(){
return !underAllStatus;
}

public void setUnderAllStatus(boolean underAllStatus) {
this.underAllStatus = underAllStatus;
}

public Paging getPaging() {
return paging;
}

public void setPaging(Paging paging) {
this.paging = paging;
}

public Integer getNum() {
return num;
}

public void setNum(Integer num) {
this.num = num;
}

public void onActionFromFirst(Integer newPageNo){
changePageNo(newPageNo);
}
public void onActionFromPrevious(Integer newPageNo){
changePageNo(newPageNo);
}
public void onActionFromNext(Integer newPageNo){
changePageNo(newPageNo);
}
public void onActionFromLast(Integer newPageNo){
changePageNo(newPageNo);
}
public void changePageNo(Integer newPageNo) {

getPaging().setPageNo(newPageNo == null ? Paging.ALL : newPageNo.intValue());
// setPaging(getPaging()); // persist!

if (newPageNo == null)
setUnderAllStatus(true);
}

public Integer[] getAllPageNumbers() {
int size = getLast().intValue() + 1;
Integer[] allPages = new Integer[size];
for (int i = 0; i < size; i++) {
allPages[i] = new Integer(i);
}
return allPages;
}

public String getPageLabel() {
return "" + (getNum().intValue() + 1);
}

public Integer getFirst() {
return new Integer(0);
}

public Integer getPrevious() {
return new Integer(getPaging().getPageNo() - 1);
}

public Integer getNext() {
return new Integer(getPaging().getPageNo() + 1);
}

public Integer getLast() {
int last = (int)Math.ceil((double)getPaging().getItemCount() / getPaging().getMaxResults()) - 1;
return new Integer(last);
}

public Integer getAll() {
return null;
}

public boolean isFirstDisabled() {
return getPaging().getPageNo() == 0;
}

public boolean isPreviousDisabled() {
return isFirstDisabled() || getPaging().getPageNo() == Paging.ALL;
}

public boolean isSelectedPage() {
return getPaging().getPageNo() == getNum().intValue();
}

public boolean isNextDisabled() {
return isLastDisabled() || getPaging().getPageNo() == Paging.ALL;
}

public boolean isLastDisabled() {
return getPaging().getPageNo() == getLast().intValue();
}

public boolean isAllDisabled() {
return getPaging().getPageNo() == Paging.ALL || getLast().intValue() == 0;
}

public boolean isNavigationDisplayed() {
return getLast().intValue() > 0;
}

@OnEvent(component="pageStatus")
public void enterPagingStatus(){
setUnderAllStatus(false);

getPaging().setPageNo(0);
// setPaging(getPaging());
}

public int getCurrentPage(){
return paging.getPageNo() + 1;

}

public int getPageCount(){
return getLast() + 1;
}
}



Ok,这个对于T4, T3也是一样的。 你只要把OrderColumn 和 PageNavigation 组件改成相应版本下面的组件就行了。 还有就是如果觉得PageNavigation看起来不是很好的话, 你也可以自己做各式各样的PageNavigation,他就只需要Paging这个类。

我把这个打包成了一个Maven项目。 如果你装了WTP的话。
运行mvn eclipse:eclipse -Dwtpversion=1.0 -DdownloadSources=true 然后再import项目到eclipse中就行了。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值