Grid算是比较T5中较复杂的一个组件,我也有篇介绍Grid怎么使用的文章。[url]http://www.iteye.com/topic/114754[/url] 但是如果我们平时需要些比较灵活的布局。 Grid组件用起来就比较别扭了。
下面我介绍下使用Loop组件实现一个灵活但是又不缺乏分页,排序功能的Grid组件的实现。
首先我们全局看下页面上是要怎样写的。
是不是比较简单。 你可以单独输出Table的头部和body部分。 这里使用了2个组件一个OrderColumn,一个是PageNavigation。 这两个组件公用了一个paging对象, 这个paging对象其实提供了对分页,和当前排序字段的支持。 下面看看page class的内容。
这里我们把paging对象保存在了session里。 然后绑定到OrderColumn和PageNavigation组件中。 请注意getItems方法。 这个是获得你要显示的数据。 这里你要先得到所有的数据的总数然后调用setItemCount方法, 然后你要通过paging中的firstResult maxResult orderProperty order(desc,ase)去获取你要显示的数据。 下面看看paging对象。
ok, 下面贴下OrderColumn, PageNavigation的代码
OrderColumn.tml
OrderColumn.java
PageNavigation.tml
PageNavigation.java
package
Ok,这个对于T4, T3也是一样的。 你只要把OrderColumn 和 PageNavigation 组件改成相应版本下面的组件就行了。 还有就是如果觉得PageNavigation看起来不是很好的话, 你也可以自己做各式各样的PageNavigation,他就只需要Paging这个类。
我把这个打包成了一个Maven项目。 如果你装了WTP的话。
运行mvn eclipse:eclipse -Dwtpversion=1.0 -DdownloadSources=true 然后再import项目到eclipse中就行了。
下面我介绍下使用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中就行了。