博客首页 注册 建议与交流 排行榜 加入友情链接
推荐 投诉 搜索: 帮助

jUsT olD tiMe

-=编程 艺术 人生=-
  hello386.cublog.cn

关于作者
姓名:豆子
职业:程序员
年龄:属狗的
位置:北京
个性介绍:
|| << >> ||
我的分类


eXtremeComponents参考文档(1)

eXtremeComponents

参考文档

Jeff Johnston

版本1.0.0

本文档允许在遵守以下两条原则的条件下被使用和传播:
1)不能凭借本文档索取任何费用
2)以任何方式(印刷物或电子版)使用和传播时本文档时,必须包含本版权申明

前言

eXtremeComponents是一系列提供高级显示的开源JSP定制标签。当前的包含 的组件为eXtremeTable,用于以表的形式显示数据。

本文档处于更新中。大部分章节我将仅仅描述如何使用eXtremeTable。当然, 为了使程序高效并具有更高的灵活性,源代码被再三重构。随后, 我认为阐述一下如 何做设计决定是值得的。我希望大家能知道使用extremeTable是多么容易,并且所 有的东西都是可配置。如果你有任何的要求和建议, 请及时通过论坛或者 extremecomponents@gmail.com和我联系。

我想感谢Chris Bauer(Hibernate开发小组)和Rod Johnson(Spring开发小组)。 Chris提供并修改了DocBook-XSL使它能生成Hibernate参考指南。Rod对于使用从Hibernate 得到的这个软件来生成Spring文档提供了支持。我现在用它来生成eXtremeComponents的文档。

译者注:如果大家有什么疑问和建议,可以通过xplucky@gmail.com和我联系。

Chapter 1. 配置

1.1. 先决条件

  • Servlet 2.3或更高版本

  • JDK 1.3.1或更高版本

最小的Jars要求:

  • commons-beanutils 1.6

  • commons-collections 3.0

  • commons-lang 2.0

  • commons-logging 1.0.4

  • standard 1.0.2

PDF导出需要的Jars:

  • minimum jars (above)

  • avalon-framework 4.0

  • batik 1.5-fop-0.20-5

  • fop 0.20.5

  • xalan 2.5.1

  • xercesImpl 2.6.1

  • xml-apis 2.0.2

XLS导出需要的Jars:

  • minimum jars (above)

  • poi-2.5.1.jar

1.2. 安装

sourceforge 下载发行包。(http://sourceforge.net/projects/extremecomp/)

在压缩文件里你能找到开始使用需要的所有东西:

  • extremecomponents.jar

  • extremecomponents.tld

  • extremecomponents.css

  • 默认的一组图片

  • 源代码

  • test.jsp (用于确认安装是否正确)

将extremecomponents.jar文件拷贝到你的工程的/WEB-INF/lib目录下。

处理TLD文件有两种方式。 你可以把extremecomponents.tld文件放到WEB-INF目录下的任何地方。 不过,为了便于管理,我喜欢把我的TLD文件都放到/WEB-INF/tld目录下。你需要根据你的extremecomponents.tld 文件的位置来修改/WEB-INF/web.xml文件的标签映射。

<taglib>
    <taglib-uri>/tld/extremecomponents</taglib-uri>
    <taglib-location>/WEB-INF/tld/extremecomponents.tld</taglib-location>
</taglib>

随后,你需要向下面一样在你的JSP里把eXtremeTable包含进来:

<%@ taglib uri="/tld/extremecomponents" prefix="ec" %>

如果你的servlet容器支持JSP 1.2 (或更高版本),它将能够自动发现TLD文件,那么你什么也不需要做。 当extremecomponents.jar被容器加载的时候,在它的META-INF目录下的extremecomponents.tld文件将被找到。 这时,你需要向下面一样在你的JSP里把eXtremeTable包含进来:

<%@ taglib uri="http://www.extremecomponents.org" prefix="ec" %>

为了使用eXtremeTable样式,从styles目录拷贝extremecomponents.css到你存放.css脚本的地方。 当然在JSP页面里,你需要提供一个到CSS的链接。就像我将我的样式表放在/styles目录下。

<%@ taglib uri="/tld/c" prefix="c" %>
<link rel="stylesheet" type="text/css" href="<c:url value="/styles/extremecomponents.css"/>">

1.3. 导出过滤器(可选)

为了使导出功能有效,你需要设置导出过滤器。这是一个仅用于导出功能的可选配置。

如下所示在/WEB-INF/web.xml里配置过滤器:

<filter>
  <filter-name>eXtremeExport</filter-name>
  <filter-class>org.extremecomponents.table.filter.ExportFilter</filter-class>
</filter>
<filter-mapping>
  <filter-name>eXtremeExport</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

过滤器还有一个可选的初始化参数,用于决定什么时候生成报头(headers)。我发现大多数的servlet容器 倾向于在调用过滤器的doFilter()方法后才设置响应报头(response headers)。然而,一些servlet容器只有在 调用过滤器的doFilter()方法前设置响应报头,过滤器才能正常工作。默认的方法是调用过滤器的doFilter()方法后 设置响应报头,你可以通过使用responseHeadersSetBeforeDoFilter这个初始化参数调整它。

<filter>
  <filter-name>eXtremeExport</filter-name>
  <filter-class>org.extremecomponents.table.filter.ExportFilter</filter-class>
    <init-param>
      <param-name>responseHeadersSetBeforeDoFilter</param-name>
      <param-value>true</param-value>
    </init-param>
</filter>

如果你使用了Sitemesh,你将需要包含SitemeshPageFilter。SitemeshPageFilter扩展了正常的 sitemesh的PageFilter,它使得正在进行导出的JSP页面不被修饰。

如下所示在/WEB-INF/web.xml里配置过滤器:

<filter>
  <filter-name>Sitemesh</filter-name>
  <filter-class>org.extremecomponents.table.filter.SitemeshPageFilter</filter-class>
</filter>
<filter-mapping>
  <filter-name>Sitemesh</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

1.4. 安装测试

使用发行包的test.jsp来测试安装。将test.jsp拷贝到web应用的最顶层, 默认的图片文件在 /images/table/子目录下。为了测试,创建相应的目录并将拷贝所有需要的图片。所有工作都完成后,你可以在浏览 器里运行test.jsp了。

提示: 我不提倡在JSP里使用脚本(scriplets),但为了不用使用框架而能进行快速测试,在test.jsp 使用脚本是唯一的办法。

Chapter 2. 概述

2.1. 引言

eXtremeTable在给定的servlet范围(scope)外取得Beans或Maps的集合用于JSP页面显示。 servelet范围的搜索顺序是:page, request, session和application。通过设定TableTage的items 属性,eXtremeTable知道哪些需要在servlet范围外被保持。

集合里的Beans是pojo,如果使用maps那么它就是键值对。你可以认为每一个bean就是表中的一行数据。 在接下来的文档中,我将使用Beans集合来代替这两种集合。

实际表使用的最小语法如下所示:

<ec:table
   items="presidents"
   action="${pageContext.request.contextPath}/presidents.run"
   imagePath="${pageContext.request.contextPath}/images/*.gif">
  <ec:row>
    <ec:column property="firstName"/>
    <ec:column property="lastName"/>
    <ec:column property="termDate"/>
  </ec:row>
</ec:table>

这就是eXtremeTable的一个典型定义。通过这些定义,你将得到格式化的列和页头,工具栏的所有 特性也能很好工作。

Chapter 3. TableTag

3.1. 引言

TableTag用来设定什么被显示并且如何进行显示。默认的eXtremeTable在servlet范围(按照page,request, session,applicaton的顺序)寻找具有名称和items属性设置相同的Beans集合(如前章所述它指Beans和Maps两种集合)。 表将遍历所有列,它使用var属性将当前行对应的bean从集合传到page范围,因此你可以从page范围中重新得到这些数据 进行操作。tableId用来唯一标识表,如果在JSP页面里包含两个或两个以上的表时需要设置它。

President bean定义如下:

public class President implements Serializable {
  private String firstName;
  private String lastName;

  public String getFirstName() {
    return firstName;
  }

  public void setFirstName(String firstName) {
    this.firstName = firstName;
  }

  public String getLastName() {
    return lastName;
  }

  public void setLastName(String lastName) {
    this.lastName = lastName;
  }
}

Beans集合需要被组装并传到servlet范围中。我喜欢使用Spring框架,因此示例将使用Spring框架的 控制器(Controller)。如果你正在使用Struts,它和Action的功能类似。如果你使用别的东西,比如直接使用 servlets,你只需要明白我所做的只是组装Beans集合并传到request范围中。

public class Presidents extends AbstractController {
  protected ModelAndView handleRequestInternal(HttpServletRequest request,
                                                 HttpServletResponse response)
    throws Exception {
    List presidents = new ArrayList();

    President president = new President();

    president.setFirstName("George");
    president.setLastName("Washington");
    presidents.add(president);

    president = new President();
    president.setFirstName("John");
    president.setLastName("Adams");
    presidents.add(president);

    request.setAttribute("presidents", presidents);

    return new ModelAndView("/demo/presidents.jsp");
}

现在你可以构造表了:

<%@ taglib uri="/tld/extremecomponents" prefix="ec" %>

<ec:table
  items="presidents"
  var="pres"
  imagePath="${pageContext.request.contextPath}/images/*.gif"
  action="${pageContext.request.contextPath}/presidents.run"
  >
  <ec:column property="firstName"/>
  <ec:column property="lastName"/>
    ${pres.lastName}
  </ec:column>
</ec:table>

从本示例中你应该知道我们将名为presidents的Beans集合以presidents为名称放到request中。 为了使表知道如何找到这个Beans集合,我们设置TableTag的items属性为presidents。同时我们定义 了两列:firstName和lastName。firstName列是最普通的用法:我们仅仅想让这列从当前bean中得到相应 firstName的值;lastName列示另外一种用法:明确取得值。

从一列中明确取得值非常有用,但是你需要理解表是如何构造行的。为了构造行,表需要对所有行进行 rowsDisplayed属性设定次数的迭代。每次迭代都从Beans里取得下一个bean并使用var属性设定的名称传入page 范围。也可以说每次迭代你都访问的是集合中当前行对应的bean。

3.2. 显示图片

为了显示图片需要设置imagePath属性:

<ec:table
  items="presidents"
  var="pres"
  imagePath="${pageContext.request.contextPath}/images/*.gif"
  >
  ...
</ec:table>

eXtremeTable将找到一个目录下的所有图片并使用特殊的语法来定义他们是那类图片。 本示例中所有的图片都直接保存在web上下文的images目录下。*.gif使eXtremeTable知道所 有的图片都是GIF格式的。在我们讨论preferences后,你将发现你可以你可以通过在 extremecomponents.properties文件中设定这个属性,而不用再整个应用的每个eXtremeTable 中包含它。

3.3. 过滤、排序和动作(Action)

eXtremeTable内嵌了过滤和排序功能,你只需要决定是否需要使用他们。你要使用的属性是 filterable和sortable,他们都是布尔值并且默认值是true。默认的所有特性都有效,你可以按照 需要来关掉一些特性。比如,如果你不想使用排序或过滤你可以把他们的属性设为false。

<ec:table
  items="presidents"
  var="pres"
  imagePath="${pageContext.request.contextPath}/images/*.gif"
  action="${pageContext.request.contextPath}/presidents.run"
  filterable="false"
  sortable="false"
  >
  ...
</ec:table>

如果你仍不确信,你可以来验证他们。首先,设置filterable和sortable为true,你将看到 eXtremeTable允许你输入关键词来过滤结果集,它也允许你通过在页头(header)上滚动鼠标来排序。 然后,设置filterable和sortable为fale,你将发现所有这些特性都不允许使用。

本示例需要指出的是使用action属性,action被用来告诉eXtremeTable当过滤或排序时如何回 到当前的页面。本例中我通过Spring框架的controller(在这里是presidents.run)来得到Beans集合。 你不需要担心传参问题,eXtremeTable将保存所有的参数并将它们和过滤器、排序、分页一起传递给 Beans集合。更详细的信息请参考ParameterTag。

3.4. 设定每页显示行数

默认地eXtremeTable一页将显示15行。你可以通过设定rowsDisplayed属性为你想显示行数的数 值来改变它。rowsDisplayed也可以在extremecomponents.properties文件中设定。(参考Preferences)。

提示:如果你想在一页中显示所有行,只需要设置showPagination为false。

3.5. 样式

TableTag关联了很多样式属性:

<ec:table
  cellspacing="0"
  cellpadding="0"
  border="0"
  width="80%"
  style=""
  styleClass=""
  />

所有这些都是可选的。

3.6. 保存表的状态

表新增了两个属性:state和stateAttr。state属性参照State接口并能插接如何保存表的状态的不同实现。

State借口如下:

public interface State {
    public void saveParameters(TableModel model, Map parameters);
    public Map getParameters(TableModel model);
}

state属性使用预设的四种状态(default、notifyToDefault、persist和notifyToPersist)之一, 你也可以插接自己的实现。default状态不维持任何状态;persist状态没有任何参数传入,将一直维持表的状态; notifyToDefault状态将一直维持表的状态直到你传入参数告诉它回到default状态;notifyToPersist状态 将一直维持当前状态直到你传入参数告诉它维持persisted状态。

stateAttr为指定参数提供了一条途径,你也可以使用属性文件在全局范围内指定它。 为了向后兼容,默认参数一直为useSessionFilterSort。

如果你想state按照不同方式工作你只要实现State接口,然后使用TableTag的state属性来指定实现类的 全路径。

作为一条首要规则当使用state属性时,需要指定tableId。这是因为state使用tableId为名保存在session里。 如果tableId不唯一,eXtremeTable将覆盖另一个同名的内容。tableId默认值为ec。

3.7. 其他属性

为了保持一致性,所有的显示特性都命名为showXXXX。他们包括showPagination、showStatusBar、 showTooltips、和showExports。

title属性将在表的上方显示标题,标题的位置根据使用的视图不同而不同。当前默认视图中标题位于表的上方 工具条的左边。更详细的信息请参考View。

你会发现还有一些属性没有被探讨,因为他们将在其他章探讨。autoIncludeParameters在ParameterTag里被探讨; retrieveRowsCallback,sortRowsCallback和filterRowsCallback在Callbacks里被探讨。

3.8. 扩展属性

大多数标签包含一系列的固定属性,这样那些已经实现的功能能够被使用。然而,eXtremeTable具有一种更具弹性的架构, 你可以添加自己的标签属性实现更多的定制工作。此外,eXtremeTable提供了非常清晰的钩子(hooks)允许你得到那些定制的 标签属性来做一些你需要的工作。

通过addExtendedAttributes()方法将扩展属性包含到eXtremeTable里:

public void addExtendedAttributes(Table table);

如果方法被覆盖TableTag将调用它。你需要做的就是扩展TableTag,覆盖addExtendedAttributes()方法,然后添加自己 的属性到表对象中。一个定制的TreeTag示例如下:

public class TreeTag extends TableTag {
    private String parentAttribute;
    private String identifier;

    public void setParentAttribute(String parentAttribute) {
        this.parentAttribute = parentAttribute;
    }

    public void setIdentifier(String identifier) {
        this.identifier = identifier;
    }

    public void addExtendedAttributes(Table table) {
        table.addAttribute(TableConstants.PARENT_ATTRIBUTE, TagUtils.evaluateExpressionAsString("parentAttribute",
                parentAttribute, this, pageContext));
        table.addAttribute(TableConstants.IDENTIFIER, TagUtils.evaluateExpressionAsString("identifier",
                identifier, this, pageContext));

        table.setFilterRowsCallback("org.extremecomponents.tree.ProcessTreeRowsCallback");
        table.setSortRowsCallback("org.extremecomponents.tree.ProcessTreeRowsCallback");
    }
}

现在你添加了属性值到table对象。

另外,你也可以定制自己的标签和自己的TLD文件。你不需要修改extremecomponents.tld文件。 你能象使用eXtremeTable里的标签一样使用自己的标签,除了使用你自己标签的参照。假如你的标签参照为mycompany 并且标签为customTable,你可以像下面一样使用他们:

<mycompany:customTable
    items="presidents"
    action="${pageContext.request.contextPath}/public/demo/presidents.jsp"
    title="Presidents"
    >
  <ec:row>
    <ec:column property="nickName"/>
  </ec:row>
</mycompany:customTable>

Chapter 4. RowTag

4.1. 引言

RowTag用来定义表中的行。

一个简单RowTag示例如下:

<ec:table
  items="presidents"
  var="pres"
  action="${pageContext.request.contextPath}/presidents.run"
  >
  <ec:row>
    <ec:column property="name"/>
    <ec:column property="term"/>
  </ec:row>
</ec:table>

4.2. 高亮显示行

使用highlightRow属性可以设置行的高亮显示,它的值为true或false,默认值为false。

<ec:table
  items="presidents"
  var="pres"
  action="${pageContext.request.contextPath}/presidents.run"
  >
  <ec:row highlightRow="true">
    <ec:column property="name"/>
    <ec:column property="term"/>
  </ec:row>
</ec:table>

设置highlightRow属性后,它将插入设置行css类的javascript脚本,默认的css 类为highlight。你可以使用highlightClass来使用定制的css类。

4.3. 样式

RowTag关联了很多样式属性:

<ec:row
  style=""
  styleClass=""
  highlightClass=""
  />

所有这些都是可选的。highlightClass设置行高亮显示时的css类; style属性定义行内联的样式;styleClass允许你定义一个行显示的css类。

4.4. Javascript属性

为了便于你对于行数据进行动态交互处理,提供了onclick、onmouseover和 onmouseout属性。

<ec:row
  onclick=""
  onmouseover=""
  onmouseout=""
  />

4.5. 扩展属性

大多数标签包含一系列的固定属性,这样那些已经实现的功能能够被使用。然而,eXtremeTable具有一种更具弹性的架构, 你可以添加自己的标签属性实现更多的定制工作。此外,eXtremeTable提供了非常清晰的钩子(hooks)允许你得到那些定制的 标签属性来做一些你需要的工作。

通过addExtendedAttributes()方法将扩展属性包含到eXtremeTable里:

public void addExtendedAttributes(Row row);

Chapter 5. ColumnTag

5.1. 引言

ColumnTag用来定义表中的列。

示例President Bean:

public class President implements Serializable {
  private String firstName;
  private String lastName;

  public String getFirstName() {
    return firstName;
  }

  public void setFirstName(String firstName) {
    this.firstName = firstName;
  }

  public String getLastName() {
    return lastName;
  }

  public void setLastName(String lastName) {
    this.lastName = lastName;
  }
}

下例生成firstName和lastName列:

<ec:table
  items="presidents"
  var="pres"
  action="${pageContext.request.contextPath}/presidents.run"
  />
  <ec:row>
    <ec:column property="firstName"/>
    <ec:column property="lastName">
      ${pres.lastName}
    </ec:column>
  </ec:row>
</ec:table>

通过对TableTag的讨论,已经知道列可以通过动态或精确的方式得到他们的值。 firstName列动态地取得相应的值,列找到当前的bean并调用相应的getFirstName()取得值。 lastName列明确地从当前bean取得值,它要求你自己取得相应的值。如下例:

<ec:table
  items="presidents"
  var="pres"
  action="${pageContext.request.contextPath}/presidents.run"
  >
  <ec:row>
    <ec:column property="lastName">
      ${pageScope.pres.lastName}
    </ec:column>
  </ec:row>
</ec:table>

从page范围中取得名为pres的bean并得到它对应的lastName属性值。如果你正使用 Beans集合请确认具有对应的getter方法;如果使用Maps集合则不需要任何别的动作, eXtremeTable能够通过属性名从Map中得到对应的值。

提供这种可选取值方法的主要原因是使你能够对其他类型的html标签提供动作支持,例如显示 一幅图片或者通过定义href使该列成为到其它页的一个链接。

<ec:table
  items="presidents"
  var="pres"
  action="${pageContext.request.contextPath}/presidents.run"
  >
  <ec:row>
    <ec:column property="lastName">
      <a href="http://goto.president.detail">${pageScope.pres.lastName}</a>
    </ec:column>
  </ec:row>
</ec:table>

切记bean中所有的属性都是可访问的,因此你甚至可以通过firstName属性 来显示下一页。请注意firstName属性是如何作为URL字符串传输的。

<ec:table
  items="presidents"
  var="pres"
  action="${pageContext.request.contextPath}/presidents.run"
  />
  <ec:row>
    <ec:column property="lastName">
      <a href="http://goto.president.detail?firstName=${pageScope.pres.firstName}">
        ${pageScope.presidents.lastName}
      </a>
    </ec:column>
  </ec:row>
</ec:table>

我将不再在任何示例中强调pageScope。JSP标签总是最先在pageScope中寻找任何对像, 因此我们总是能安全地返回正确的bean。

5.2. Cell

每一列总是被实现Cell接口的对象修饰,你可以认为Cell是一个为了html显示或导出而返回格式化值的对象。 发行包包含的Cell有DisplayCell、DateCell、 NumberCell和RowCountCell。 DisplayCell是仅仅显示列值的默认cell;DateCell使用parse属性(可选)和format属性来格式化对应的属性值; NumberCell使用format属性来格式化对应的属性值;RowCountCell显示当前行。

提示:为了避免混乱并提高灵活性Cell接口已经被修改。而且对于区别 如何处理html和导出显示值也不是很清晰。以前列值作为html显示,列的propertyValue作为导出使用。 另外列值和propertyValue已经重写,他们以前在view中是不能被访问的。

cell现在是singleton并且不再线程安全,改变的原因是为了Cell接口能更简单地被使用。 init()和destroy()方法作为singleton更灵活但是处于一种混乱的状态。

Cell接口如下:

public interface Cell {
    /**
     * The display that will be used for the exports.
     */
    public String getExportDisplay(TableModel model, Column column);

    /**
     * The html that will be displayed in the table.
     */
    public String getHtmlDisplay(TableModel model, Column column);
}

现在得到导出和html显示存在明显的区别。更重要的,需要返回字符串。列值和属性值不再 需要设置。

DisplayCell是扩展AbstractCell的最简单的Cell。AbstractCell定义 的虚拟方法getCellValue用来返回cell的值。虽然AbstractCell在一些情况下是有用的, 但更多情况下只需要直接实现Cell接口。

DisplayCell:

public class DisplayCell extends AbstractCell {
    public String getExportDisplay(TableModel model, Column column) {
        return column.getPropertyValueAsString();
    }

    protected String getCellValue(TableModel model, Column column) {
        return column.getValueAsString();
    }
}

AbstractCell:

public abstract class AbstractCell implements Cell {
    public String getExportDisplay(TableModel model, Column column) {
        return getCellValue(model, column);
    }

    public String getHtmlDisplay(TableModel model, Column column) {
        HtmlBuilder html = new HtmlBuilder();
        CellBuilder.tdStart(html, column);
        CellBuilder.tdBody(html, getCellValue(model, column));
        CellBuilder.tdEnd(html);
        return html.toString();
    }

    /**
     * A convenience method to get the display value.
     */
    protected abstract String getCellValue(TableModel model, Column column);
}

现在你应该知道Cell是多么简单。只需通过实现Cell接口或扩展AbstractCell来定制你自己的Cell, 并设置列标签的Cell属性为类的全路径。例如: 如果你定制了一个名为MyCell的Cell,那么你可以像下面一样使用它:

<ec:column property="firstName" cell="com.mycompany.cell.MyCell"/>

如果你改变列的数据,那么过滤或排序可能没有意义。切记我的意思是如果你人为地改变数据, 而不是使用样式对它进行包装或作为<a href>包含。 如果你的定制cell显示数据的树状视图,或者是一幅图片, 那么过滤和排序等一切逻辑操作都是没有意义的。

5.3. Filter Cell

列的filterCell属性控制过滤器如何显示,它和cell属性非常相像并且也是实现Cell接口。 已经定义了两个过滤器cells:默认的和droplist。默认的是一个输入框元素,除非你确信你需要使这列可以进行过滤, 否则你不需要做任何事。

你可以像下面一样使用droplist过滤器Cell:

<ec:table
  items="presidents"
  action="${pageContext.request.contextPath}/presidents.run"
  >
  <ec:row>
    <ec:column property="status" filterCell="droplist"/>
  </ec:row>
</ec:table>

filterCell也允许你定义定制的过滤器,所有你必须做的就是实现Cell接口或者扩展AbstractCell, 并设置列标签的Cell属性为类的全路径。例如,如果你定制了一个名为MyCell的Cell,那么你可以像下面一样使用它:

<ec:column property="firstName" filterCell="com.mycompany.cell.MyFilterCell"/>

参阅Cell节了解如何创建你自己定制Cells的更多信息。

5.4. Header Cell

headerCell属性控制headers如何显示,它和cell属性非常相像并且也是实现Cell接口。 默认header cell作为文本显示,包含排序逻辑。

headerCell也允许你定义定制的过滤器,所有你必须做的就是实现Cell接口或者扩展AbstractCell, 并设置列标签的Cell属性为类的全路径。例如,如果你定制了一个名为MyCell的Cell,那么你可以像下面一样使用它:

<ec:column property="firstName" headerCell="com.mycompany.cell.MyHeaderCell"/>

参阅Cell节了解如何创建你自己定制Cells的更多信息。

5.5. 样式

ColumnTag关联了很多样式属性:

<ec:column
  width=""
  style=""
  styleClass=""
  headerStyle=""
  headerClass=""
  filterStyle=""
  filterClass=""
  />

所有这些都是可选的。style属性定义列内联的样式;styleClass允许你定义一个列显示的css类; headerClass属性允许你改变header列的css类;filterClass属性允许你改变filter列的css类。

5.6. 解析和格式化

解析和格式化属性被用在日期和货币的显示上。

和date交互的工作依赖于你的bean属性是否是一个字符串或者是一个Date对象。 如果是一个字符串那么你就需要确定parse属性,parse属性是按照模板定义来解析一个字符串为 一个日期对象。如果bean中的属性是日期型对象则不需要添加parse属性。不论如何你都需要设置format属性。 format属性按你提供的模板对值进行格式化。

本示例中使用MM/dd/yyyy模板格式化日期型值。因为bean中的born属性值为字符串,所以我们需要 使用parse属性来将它转换成日期型数值。

<ec:column property="born" cell="date" parse="yyyy-MM-dd" format="MM/dd/yyyy"/>

对于货币只需要设置format属性:

<ec:column property="payroll" cell="currency" format="###,###,##0.00"/>

很多时候在extremeTable中,你使用同样的模版来解析和格式化日期和货币值。 所以便利的方法是在你自己的extremecomponents.properties文件中定义解析和格式化属性。 参阅Preferences章了解更多信息。

5.7. 过滤和排序

你可能记得在TableTag中看见过filterable和sortable属性,ColumnTag中也有相同的属性。 列的filterable和sortable属性将覆盖表的filterable和sortable属性设置。当你需要除了对表中的一、两列之外的 所有列进行过滤和排序时,十分便利。

<ec:table
  items="presidents"
  action="${pageContext.request.contextPath}/presidents.run"
  >
  <ec:row>
    <ec:column property="firstName" filterable="false"/>
    <ec:column property="lastName" sortable="false"/>
  </ec:row>
</ec:table>

5.8. Calc

列新增了两个属性:calc和calcTitle:

<ec:column property="data" calc="total" calcTitle="Total:" />

calc属性实现具有唯一方法的Calc接口:

public interface Calc {
    public Number getCalcResult(TableModel model, Column column);
}

它传入model和column,并返回一个Number型的值。默认的实现为总计和平均值。

为了使用定制的Calc,只需要使用ColumnTag的calc属性来指定实现Calc接口的实现类的 全路径。

Calc为singleton并且不是线程安全的,因此不要定义任何类变量。

5.9. 允许和不允许视图

viewsAllowed属性制定类允许使用的视图。视图包括:html、pdf、xls、csv,以及任何定制的视图。 如果你指定一个或几个视图,那么列仅能使用这些指定的视图。例如:你指定viewsAllowed="pdf",这意味着 这列只允许PDF导出,而不能进行其他格式的导出或html视图。

<ec:table
  items="presidents"
  action="${pageContext.request.contextPath}/presidents.run"
  >
  <ec:row>
    <ec:column property="firstName"/>
    <ec:column property="lastName" viewsAllowed="pdf"/>
  </ec:row>
</ec:table>

viewsDenied属性制定类允许使用的视图。视图包括:html、pdf、xls、csv,以及任何定制的视图。 如果你指定一个或几个视图,那么列仅这些指定的视图不能被使用。例如:你指定viewsDenied="html",这意味着 这列不允许使用html试图,但能进行任何形式的导出。

<ec:table
  items="presidents"
  action="${pageContext.request.contextPath}/presidents.run"
  >
  <ec:row>
    <ec:column property="firstName"/>
    <ec:column property="lastName" viewsDenied="html"/>
  </ec:row>
</ec:table>

5.10. 其他属性

title属性用来为header设定一个描述性的名称。如果你不定义title那么列将使用属性名。 如果你不想显示任何title,你只需要设置title属性值为一个空白(whitespace)。

<ec:table
  items="presidents"
  action="${pageContext.request.contextPath}/presidents.run"
  title="Presidents"
  >
  <ec:row>
    <ec:column property="firstName"/> //title shows as First Name
    <ec:column property="firstName" title="First Name"/> //title shows as First Name
    <ec:column property="firstName" title=" "/> //no title shows up
  </ec:row>
</ec:table>

5.11. 扩展属性

大多数标签包含一系列的固定属性,这样那些已经实现的功能能够被使用。然而,eXtremeTable具有一种更具弹性的架构, 你可以添加自己的标签属性实现更多的定制工作。此外,eXtremeTable提供了非常清晰的钩子(hooks)允许你得到那些定制的 标签属性来做一些你需要的工作。

通过addExtendedAttributes()方法将扩展属性包含到eXtremeTable里:

public void addExtendedAttributes(Column column);

如果方法被覆盖ColumnTag将调用它。你需要做的就是扩展ColumnTag,覆盖addExtendedAttributes()方法,然后添加自己 的属性到列对象中。一个定制的CustomTag示例如下:

public class MyCustomTag extends ColumnTag {
  private String customAttributeOne;

  public String getCustomAttributeOne() {
    return customAttributeOne;
  }

  public void setCustomAttributeOne(String customAttributeOne) {
    this.customAttributeOne = customAttributeOne;
  }

  public void addExtendedAttributes(Column column) {
    column.addAttribute("customAttributeOne", customAttributeOne);
  }
}

现在你添加了属性值到Column对象,现在你可以像下例一样来定制cell:

public class MyCustomCell implements Cell {
  public String getHtmlDisplay(TableModel model, Column column) {
    Object customAttributeOne = column.getAttribute("customAttributeOne")
    String customAttributeOne = column.getAttributeAsString("customAttributeOne")
  }
}

另外,你也可以定制自己的标签和自己的TLD文件。你不需要修改extremecomponents.tld文件。 你能象使用eXtremeTable里的标签一样使用自己的标签,除了使用你自己标签的参照。假如你的标签参照为mycompany 并且标签为customColumn,你可以像下面一样使用他们:

<ec:table
    items="presidents"
    action="${pageContext.request.contextPath}/public/demo/presidents.jsp"
    title="Presidents"
    >
  <ec:row>
    <mycompany:customColumn
               property="hello"
               cell="com.mycompany.cell.MyCustomCell"
               customAttributeOne="Hello World"/>
  </ec:row>
</ec:table>

Chapter 6. ParameterTag

6.1. 引言

eXtremeTable能够指定是否处理所有的参数。默认为处理所有的参数,这意味着当你进行 过滤、排序、分页时,所有的参数都被eXtremeTable保存并传到JSP中。通常这是你需要的功能, 然而,有时候你需要只允许一些特定的参数保存到eXtremeTable中。我喜欢把它看作锁定extremeTable, 可以通过设置表的autoIncludeParameters属性值为false来到达目的:

<ec:table
  items="presidents"
  action="${pageContext.request.contextPath}/presidents.run"
  autoIncludeParameters=”false”
  >
  ...
</ec:table>

甚至当表被锁定时,你仍然可以通过简单地使用parameter标签来包含一些你想使用的参数。下例 包含了foo参数:

<ec:table
  items="presidents"
  action="${pageContext.request.contextPath}/presidents.run"
  autoIncludeParameters=”false”
  >
  <ec:parameter name=”foo” value=”${param.foo}”/>
  ...
</ec:table>

现在所有的eXtremeTable参数都被锁定。但过滤、排序和翻页时,foo参数仍将被传递。

Chapter 7. ExportTag

7.1. 引言

eXtremeTable具有导出不同格式文件的功能,导出的数据为过滤和排序后的所有结果集, 分页不会影响返回的结果集。换句话说,如果表数据分多页显示,那么所有页的数据都将被导出。 导出的格式为Microsoft Excel (OpenOffice Calc)、PDF和CSV。

使用ExportXlsTag导出Microsoft Excel (OpenOffice Calc):

<ec:table
  items="presidents"
  action="${pageContext.request.contextPath}/presidents.run"
  />
  <ec:exportXls
    fileName="presidents.xls"
    tooltip="Export Excel"/>
  ...
</ec:table>

使用ExportPdfTag导出PDF。所有要做的就是指定fileName属性和一些样式属性:

<ec:table
  items="presidents"
  action="${pageContext.request.contextPath}/presidents.run"
  />
  <ec:exportPdf
    fileName="presidents.pdf"
    tooltip="Export PDF"
    headerColor="blue"
    headerBackgroundColor="red"
    headerTitle="Presidents"/>
  ...
</ec:table>

使用ExportCsvTag导出CSV。当使用CSV导出是默认的分隔符为‘,’(comma)。你可以使用 delimiter属性来指定为其他的符号。下面为指定‘|’(pipe)为CSV分隔符的示例:

<ec:table
  items="presidents"
  action="${pageContext.request.contextPath}/presidents.run"
  />
  <ec:exportCsv
    fileName="presidents.txt"
    tooltip="Export CSV"
    delimiter="|"/>
  ...
</ec:table>

你可以通过指定view属性来导出其他文件格式。eXtremeTable视图实现View接口并是 可插接的。参阅View章了解更多信息。

7.2. 扩展属性

大多数标签包含一系列的固定属性,这样那些已经实现的功能能够被使用。然而,eXtremeTable具有一种更具弹性的架构, 你可以添加自己的标签属性实现更多的定制工作。此外,eXtremeTable提供了非常清晰的钩子(hooks)允许你得到那些定制的 标签属性来做一些你需要的工作。

通过addExtendedAttributes()方法将扩展属性包含到eXtremeTable里:

public void addExtendedAttributes(Export export);

如果方法被覆盖ExportTag将调用它。你需要做的就是扩展ExportTag,覆盖addExtendedAttributes()方法,然后添加自己 的属性到导出对象中。

一个定制的ExportCsvTag示例如下:

public class ExportCsvTag extends ExportTag {
  private String delimiter;

  public String getDelimiter() {
        return delimiter;
  }

  public void setDelimiter(String delimiter) {
        this.delimiter = delimiter;
  }

  public void addExtendedAttributes(Export export) {
      String view = export.getView();
      if (StringUtils.isBlank(view)) {
          export.setView(TableConstants.VIEW_CSV);
          export.setImageName(TableConstants.VIEW_CSV);
      }
      export.addAttribute(CsvView.DELIMITER, getDelimiter());
  }
}

现在你添加了属性值到Export对象,下面是CsvView实现的一部分:

public class CsvView implements View {
  public void body(TableModel model, Column column) {
    Export export = model.getExportHandler().getCurrentExport();
  }
}

另外,你也可以定制自己的标签和自己的TLD文件。你不需要修改extremecomponents.tld文件。 你能象使用eXtremeTable里的标签一样使用自己的标签,除了使用你自己标签的参照。假如你的标签参照为mycompany 并且标签为customExport,你可以像下面一样使用他们:

<ec:table
    items="presidents"
    action="${pageContext.request.contextPath}/public/demo/presidents.jsp"
    title="Presidents"
    >
  <mycompany:customExport fileName="presidents.txt" delimiter="|"/>
  ...
</ec:table>

Chapter 8. Callbacks

8.1. 引言

Callbacks被用于重新得到(retrieve)、过滤和排序行数据。eXtremeTable为每个callback提供了一个定制实现。 首先,载入所有的元数据,元数据为所有eXtremeTable标签的所有属性;接着在eXtremeTable的model中调用 execute方法。eXtremeTable使用execute方法决定如何通过调用每个callback的接口来重新得到、过滤和排序行数据。 这三个callback的接口是:RetrieveRowsCallback、FilterRowsCallback和SortRowsCallback。

callbacks为singleton并且不是线程安全的,因此不要定义任何类变量。

8.2. RetrieveRowsCallback

RetrieveRowsCallback的默认实现在servlet范围内寻找具有名称和TableTag 的items属性设置相同的Beans集合。为了使用定制的callback,只要实现RetrieveRowsCallback接口, 然后使用retrieveRowsCallback属性来指定实现类的全路径:

<ec:table
  var="pres"
  action="${pageContext.request.contextPath}/presidents.run"
  retrieveRowsCallback="com.mycompany.callback.MyCustomCallback"
  />

RetrieveRowsCallback接口如下所示:

public interface RetrieveRowsCallback {
  public Collection retrieveRows(TableModel model) throws Exception;
}

只有一个方法需要实现,传入TableModel并返回一个集合,集合为Beans或Maps集合。 通过得到TableModel,就拥有了TableTag的所有元数据并能访问Context。能够访问Context非常重要, 这意味着你访问web容器的任何东西。

8.3. FilterRowsCallback

FilterRowsCallback的默认实现得到Beans集合,通过实现jakarta Predicate接口进行过滤, 过滤值从eXtremeTable的filter输入框中取得。为了使用定制的callback,只要实现FilterRowsCallback接口, 然后使用filterRowsCallback属性来指定实现类的全路径:

<ec:table
  var="pres"
  action="${pageContext.request.contextPath}/presidents.run"
  filterRowsCallback="com.mycompany.callback.MyCustomCallback"
  />

FilterRowsCallback接口如下所示:

public interface FilterRowsCallback {
  public Collection filterRows(TableModel model, Collection rows) throws Exception;
}

只有一个方法需要实现,传入TableModel并返回一个集合。你只需像eXtremeTable对 每个callback的默认实现一样来定制自己的callback。

8.4. SortRowsCallback

SortRowsCallback的默认实现得到Beans集合,使用jakarta BeanComparator进行排序, 排序值当用户点击列头时取得。为了使用定制的callback,只要实现SortRowsCallback接口, 然后使用sortRowsCallback属性来指定实现类的全路径:

<ec:table
  var="pres"
  action="${pageContext.request.contextPath}/presidents.run"
  sortRowsCallback="com.mycompany.callback.MyCustomCallback"
  />

SortRowsCallback接口如下所示:

public interface SortRowsCallback {
  public Collection sortRows(TableModel model, Collection rows) throws Exception;
}

只有一个方法需要实现,传入TableModel并返回一个集合。你只需像eXtremeTable对 每个callback的默认实现一样来定制自己的callback。

 原文地址 http://www.blogjava.net/lucky/articles/33380.html
发表于: 2007-11-20,修改于: 2007-11-20 14:01,已浏览1460次,有评论0条 推荐 投诉


网友评论
 发表评论