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的討論,已經知道列可以通過動態(tài)或精確的方式得到他們的值。
firstName列動態(tài)地取得相應的值,列找到當前的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 >${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 >
${pageScope.presidents.lastName}
</a>
</ec:column>
</ec:row>
</ec:table>
我將不再在任何示例中強調pageScope。JSP標簽總是最先在pageScope中尋找任何對像,
因此我們總是能安全地返回正確的bean。
每一列總是被實現Cell接口的對象修飾,你可以認為Cell是一個為了html顯示或導出而返回格式化值的對象。
發(fā)行包包含的Cell有DisplayCell、DateCell、 NumberCell和RowCountCell。
DisplayCell是僅僅顯示列值的默認cell;DateCell使用parse屬性(可選)和format屬性來格式化對應的屬性值;
NumberCell使用format屬性來格式化對應的屬性值;RowCountCell顯示當前行。
提示:為了避免混亂并提高靈活性Cell接口已經被修改。而且對于區(qū)別
如何處理html和導出顯示值也不是很清晰。以前列值作為html顯示,列的propertyValue作為導出使用。
另外列值和propertyValue已經重寫,他們以前在view中是不能被訪問的。
cell現在是singleton并且不再線程安全,改變的原因是為了Cell接口能更簡單地被使用。
init()和destroy()方法作為singleton更靈活但是處于一種混亂的狀態(tài)。
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顯示存在明顯的區(qū)別。更重要的,需要返回字符串。列值和屬性值不再 需要設置。
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節(jié)的到如何創(chuàng)建你自己定制Cells的更多信息。
headerCell屬性控制headers如何顯示,它和cell屬性非常相像并且也是實現Cell接口。 默認header
cell作為文本顯示,包含排序邏輯。
headerCell也允許你定義定制的過濾器,所有你必須做的就是實現Cell接口或者擴展AbstractCell,
并設置列標簽的Cell屬性為類的全路徑。例如,如果你定制了一個名為MyCell的Cell,那么你可以像下面一樣使用它:
<ec:column property="firstName" headerCell="com.mycompany.cell.MyHeaderCell"/>
參閱Cell節(jié)了解如何創(chuàng)建你自己定制Cells的更多信息。
ColumnTag關聯(lián)了很多樣式屬性:
<ec:column
width=""
style=""
styleClass=""
headerStyle=""
headerClass=""
filterStyle=""
filterClass=""
/>
所有這些都是可選的。style屬性定義列內聯(lián)的樣式;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>