当前位置: 首页 > 工具软件 > Tapestry > 使用案例 >

Tapestry分页

魏朗
2023-12-01

Tapestry Table组件提供了分页的功能, 但是以前以为它只能是一次性的吧所有元素都fetch出来,然后把这些元素交给Table去处理。错了。 其实Tapetry的Table组件太强大了, 它已经把这个问题考虑了。只fetch当前页的数据。
 
以前做从数据库中查找数据  然后再分页时, 都是使用For 或者 Foreach组件,然后自己写一个PageNavigation组件(用于显示第几页 有多少页),还有ColumnSort组件。 其实Table已经把这些都写好。而且每次写分页时都非常麻烦。 要注意的东西太多了。
 
我花了 大概半天的时间看了Table组件的实现。 其实Table组件的核心是这些组件(Table FormTable是由下列这些组件组合而成的)
TableView              采集Table需要的信息, Source Column etc
TableColumns         显示Table  表头的信息
TableFormRows      象For组件一样list 每行的内容(用在Form中,可以提交数据)
TableRows             象For组件一样list 每行的内容(不用在Form中)
TableValues           应该被TableRows或TableFormRows包含, 每行的值
TablePages            显示Page Navigation
TableFormPages     显示Page Navigation(在Form里)
 
详细信息可以结合WorkBench的Table例子看Table FormTable的源码, 应该能对Table有个比较深入的理解。
 
下面说说怎么让Table fetch当前页面所需的数据。不知道大家有没有注意到TableView的source属性:
source
 
Object[]
Collection
Iterator
IBasicTableModel
 
in You must provide either both source and columns parameters or the tableModel parameter   The data to be displayed by the component. This parameter must be used in combination with the columns parameter. The parameter must be an array of values, a collection, an iterator, or an object implementing the IBasicTableModel interface.
 
我们一般都是使用Object[] Collection 和 Iterator作为table的source, 有没有注意IBasicTableModel呢? 我们先看看这个接口。
 
package org.apache.tapestry.contrib.table.model;
import java.util.Iterator;
/**
 * A simplified version of the table model that concerns itself only with
 * providing the data on the current page.
 *
 * @author mindbridge
 * @since 3.0
 */
public interface IBasicTableModel
{
    /**
     *  Returns the number of all records
     *  @return the number of all rows
     **/
    int getRowCount();
    /**
     *  Returns the rows on the current page.
     *  @param nFirst the index of the first item to be dispayed
     *  @param nPageSize the number of items to be displayed
     *  @param objSortColumn the column to sort by or null if there is no sorting
     *  @param bSortOrder determines the sorting order (ascending or descending)
     **/
    Iterator getCurrentPageRows(int nFirst, int nPageSize, ITableColumn objSortColumn, boolean bSortOrder);
}

 
是不是有些清晰了呢? 两个方法, 没错就是上面javadoc上面说的那样。 我们返回一个实现了IBasicTableModel的类就能做到Fetch当前页的数据: 我做了一个小例子基本包括了Table的用法。我也是仿照WorkBench的Table的例子,但是我用的是Fetch当前页面的Locale,还写了一个自定义Column。 如下(注意加粗的部分):
 
TablePage.html

border@Border" subTitle="Tapestry">

<form jwcid="@Form">
 
 
  
        source="ognl:model"
        columns="literal: !locale:toString(), !language:displayLanguage, !country:displayCountry,
               !variant:displayVariant, !isoLanguage:ISO3Language, !isoCountry:ISO3Country, =displayNameColumn"
               pageSize="ognl:7"
   >
   
    
     
           
           rows@contrib:TableRows" row="ognl:currLocale">
           

           
          
           
           
          
   

          

          

  
 
 


 
 
 

 




 
TablePage.java
 
package com.dengyin.tapestry.pages;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import org.apache.tapestry.annotations.InitialValue;
import org.apache.tapestry.annotations.Meta;
import org.apache.tapestry.annotations.Persist;
import org.apache.tapestry.contrib.table.model.IBasicTableModel;
import org.apache.tapestry.contrib.table.model.ITableColumn;
import org.apache.tapestry.contrib.table.model.simple.ITableColumnEvaluator;
import org.apache.tapestry.contrib.table.model.simple.SimpleTableColumn;
import com.dengyin.tapestry.DemoBasePage;
@Meta(
  { "anonymous-access=true", "admin-page=false" })
public abstract class TablePage extends DemoBasePage {
 
 @Persist("session")
 @InitialValue("new java.util.HashSet()")
 public abstract Set getSelectedLocales();
 public abstract void setSelectedLocales(Set set);
 
 publicabstract Locale getCurrLocale();
 @InitialValue("new java.util.HashSet()")
 public abstract Set getListItems();
 public abstract void setListItems(Set set);
 
 public boolean getCheckboxSelected(){
  return getSelectedLocales().contains(getCurrLocale());
 }
 
 public void setCheckboxSelected(boolean checked){
  Set selectedLocales = getSelectedLocales();
  if (checked){
   selectedLocales.add(getCurrLocale());
  }else{
   selectedLocales.remove(getCurrLocale());
  }
 
  //make persist
  setSelectedLocales(selectedLocales);
 }
 
 public ITableColumn getDisplayNameColumn(){
  return new SimpleTableColumn("displayName", "displayName", new ITableColumnEvaluator(){
   private static final long serialVersionUID = 6228368700745851970L;
   public Object getColumnValue(ITableColumn objColumn, Object objRow) {
    Locale locale = (Locale) objRow;
    return locale.getDisplayName();
   }
  
  }, false
   
  );
 }
 
 public IBasicTableModel getModel(){
  return new IBasicTableModel(){
   public int getRowCount() {
    return Locale.getAvailableLocales().length;
   }
   public Iterator getCurrentPageRows(int nFirst, int nPageSize, ITableColumn objSortColumn, boolean bSortOrder) {
    int count = Locale.getAvailableLocales().length;
    int begInIndex = nFirst; //nFirst the index of the element. not the page index
    int endIndex = nFirst + nPageSize -1;
    //if the last page don&apost contain pageSize&aposs elements, it will throw ArrayIndexOutOfBoundsException.
    // so we need to catch this.
    if (endIndex > count -1){
     endIndex = count -1;
   }
    List result = new ArrayList ();
    for(int i = begInIndex; i<=endIndex; i++ ){
     result.add(Locale.getAvailableLocales()[i]);
    }
   
    return result.iterator();
   }
  
  };

 }
 public abstract Locale getItem();
 
 public void listItems(){
  setListItems(getSelectedLocales());
 }
}

 

getCurrentPageRows 方法中我们可以通过ITableColumn objSortColumn 去进行排序(当有需要排序时这个参数不为null), bSortOrder 为是升序还是降序排列。我们可以通过objSortColumn得到需要排序的字段, bSortOrder 是按种方式排序, 我们就可以构造SQL语句,把排序的工作交给数据库, 然后得到一个排好序的List, 然后在截取这个List中当前页的值就行了。

 类似资料: