幸せのちから

平凡的世界
看似平常实崎岖
成如容易却艰辛

Chapter 5. ColumnTag

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>

posted on 2006-02-27 10:01 Lucky 阅读(721) 评论(0)  编辑  收藏 所属分类: extremeComponents


只有注册用户登录后才能发表评论。


网站导航:
 
<2006年2月>
2930311234
567891011
12131415161718
19202122232425
2627281234
567891011

导航

随笔分类(125)

文章分类(5)

日本語

搜索

积分与排名

最新随笔

最新评论