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。
每一列总是被实现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显示数据的树状视图,或者是一幅图片, 那么过滤和排序等一切逻辑操作都是没有意义的。
列的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的更多信息。
headerCell属性控制headers如何显示,它和cell属性非常相像并且也是实现Cell接口。 默认header
cell作为文本显示,包含排序逻辑。
headerCell也允许你定义定制的过滤器,所有你必须做的就是实现Cell接口或者扩展AbstractCell,
并设置列标签的Cell属性为类的全路径。例如,如果你定制了一个名为MyCell的Cell,那么你可以像下面一样使用它:
<ec:column property="firstName" headerCell="com.mycompany.cell.MyHeaderCell"/>
参阅Cell节了解如何创建你自己定制Cells的更多信息。
ColumnTag关联了很多样式属性:
<ec:column
width=""
style=""
styleClass=""
headerStyle=""
headerClass=""
filterStyle=""
filterClass=""
/>
所有这些都是可选的。style属性定义列内联的样式;styleClass允许你定义一个列显示的css类;
headerClass属性允许你改变header列的css类;filterClass属性允许你改变filter列的css类。
解析和格式化属性被用在日期和货币的显示上。
和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章了解更多信息。
你可能记得在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>
列新增了两个属性: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并且不是线程安全的,因此不要定义任何类变量。
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>
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>
大多数标签包含一系列的固定属性,这样那些已经实现的功能能够被使用。然而,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>