HtmlDataTable組件屬于UIData家族的HTML數(shù)據(jù)列表實(shí)現(xiàn),組件中提供了rowStyleClass等方法來(lái)控制行的顯示,,如果你在rowStyleClass中加入兩個(gè)樣式類,并使用逗號(hào)分開,那么渲染的每一行會(huì)交替使用這兩個(gè)樣式類進(jìn)行顯示,同理多個(gè)樣式類也會(huì)循環(huán)交替顯示。但是如果我想根據(jù)業(yè)務(wù)的情況具體指定某行顯示成特定的樣式,HtmlDataTable就 無(wú)能為力了,然而這種業(yè)務(wù)又很常見,比如我想高亮顯示列表中時(shí)間過(guò)期的行等等......
下面是一個(gè)例子,顯示了我的藏書列表,我想讓計(jì)算機(jī)類書籍的行使用紅色背景,文學(xué)類書籍的行使用白色背景,經(jīng)濟(jì)學(xué)類書籍的行使用藍(lán)色列表。
1.首先是Book模型
package net.blogjava.fangshun.book;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.faces.model.SelectItem;


/** *//**
* 書籍模型
* @author shun.fang
*
*/

public class Book implements Serializable
{
private int id; //書籍編號(hào)
private String name; //書籍名稱
private int type; //書籍類型

public Book()
{
}

/** *//**
* type
* @param id
* @param name
* @param type
*/

public Book(int id, String name, int type)
{
// TODO Auto-generated constructor stub
this.id = id;
this.name = name;
this.type = type;
}

public int getId()
{
return id;
}

public void setId(int id)
{
this.id = id;
}

public String getName()
{
return name;
}

public void setName(String name)
{
this.name = name;
}

public int getType()
{
return type;
}

public void setType(int type)
{
this.type = type;
}
public static final int COMPUTER_BOOK = 1; //計(jì)算機(jī)類
public static final int ART_BOOK = 2; //文學(xué)類
public static final int ECONOMY_BOOK = 3; //經(jīng)濟(jì)類
private List<SelectItem> items;

/** *//**
* 為下拉菜單提供模擬數(shù)據(jù)
* @return
*/

public List<SelectItem> getItems()
{

if(items == null)
{
items = new ArrayList<SelectItem>();
SelectItem item = new SelectItem();
item.setLabel("計(jì)算機(jī)類");
item.setValue(COMPUTER_BOOK);
items.add(item);
item = new SelectItem();
item.setLabel("文學(xué)類");
item.setValue(ART_BOOK);
items.add(item);
item = new SelectItem();
item.setLabel("經(jīng)濟(jì)學(xué)類");
item.setValue(ECONOMY_BOOK);
items.add(item);
}
return items;
}
}

2. book的列表模型
package net.blogjava.fangshun.book;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.faces.component.UIData;
import javax.faces.model.ListDataModel;


/** *//**
* 書籍列表模型
* @author shun.fang
*
*/

public class BookList implements Serializable
{
// 綁定使用此BookList作為數(shù)據(jù)源的UIData組件,常使用的是HtmlDataTable這個(gè)實(shí)現(xiàn)組件
// 這樣可以通過(guò)調(diào)用BookList模型來(lái)間接訪問(wèn)到HtmlDataTable組件,以便控制組件
// 內(nèi)部的狀態(tài)
private UIData uiData;
private ListDataModel books;

//UIData組件的values屬性可以直接讀取DataModel家族的對(duì)象
//這里沒有返回Collection集合對(duì)象,是為了在自定義的BookListDataModel
//對(duì)象中控制UIData組件的狀態(tài)

public ListDataModel getBooks()
{

if(books == null)
{
books = new BookListDataModel(createBooks());
}
return books;
}


public void setBooks(ListDataModel books)
{
this.books = books;
}


public UIData getUiData()
{
return uiData;
}


public void setUiData(UIData uiData)
{
this.uiData = uiData;
}

/** *//**
* 創(chuàng)建模擬數(shù)據(jù)
* @return List<Book>
*/

public List<Book> createBooks()
{
//使用HashMap是為了打亂數(shù)據(jù)的排序
Map<Integer, Book> bs = new HashMap<Integer, Book>();

for(int i = 0; i < 50; i++)
{
bs.put(i, new Book(i, "book_" + i, (i%3+1)));
}
List<Book> lst = new ArrayList<Book>();
lst.addAll(bs.values());
return lst;
}
}

3. 自定義的數(shù)據(jù)模型
package net.blogjava.fangshun.book;

import java.util.List;

import javax.faces.context.FacesContext;
import javax.faces.el.VariableResolver;
import javax.faces.model.ListDataModel;

import org.apache.myfaces.component.html.ext.HtmlDataTable;


/** *//**
* 集成了ListDataModel為Book模型提供自定義樣式的支持
* @author shun.fang
*
*/

public class BookListDataModel extends ListDataModel
{

public BookListDataModel(List<Book> books)
{
super(books);
}

/** *//**
* 覆寫了DataModel對(duì)象的getRowData方法,每次uiData組件從模型列表獲取新一行記錄
* 的時(shí)候,是從這里發(fā)起的,所以在這里可以通過(guò)獲取uiData組件,來(lái)對(duì)uiData組件的狀態(tài)進(jìn)行
* 調(diào)整。目前的調(diào)整就是根據(jù)業(yè)務(wù)的需要對(duì)uiData組件的每一行樣式進(jìn)行特殊指定。
*/
@Override

public Object getRowData()
{
// TODO Auto-generated method stub
/////////////////////////////////////////////////////////////
//通過(guò)變量解析獲取request scope中的BookList列表模型
FacesContext facesContext = FacesContext.getCurrentInstance();
VariableResolver vr = facesContext.getApplication().getVariableResolver();
BookList bookList = (BookList)vr.resolveVariable(facesContext, "booking");
/////////////////////////////////////////////////////////////
//間接得到綁定BookList列表模型的uiData組件,并向下轉(zhuǎn)型成HtmlDataTable(myfaces擴(kuò)展類型)組件
HtmlDataTable table = (HtmlDataTable)bookList.getUiData();
//獲取當(dāng)前行的Book實(shí)例
Book book = (Book)super.getRowData();
//根據(jù)當(dāng)前行Book實(shí)例的業(yè)務(wù)特征為HtmlDataTable組件設(shè)置渲染行樣式
setCurrentRowStyle(table, book.getType());
return book;
}

/** *//**
* 根據(jù)不同的類型,設(shè)置當(dāng)前行的樣式
* @param table
* @param type
*/

private void setCurrentRowStyle(HtmlDataTable table, int type)
{

switch (type)
{
case Book.COMPUTER_BOOK:
//System.out.println("computers");
table.setRowStyleClass("computers"); //設(shè)置計(jì)算機(jī)書籍樣式
break;
case Book.ART_BOOK:
//System.out.println("arts");
table.setRowStyleClass("arts"); //設(shè)置文學(xué)書籍樣式
break;
case Book.ECONOMY_BOOK:
//System.out.println("C");
table.setRowStyleClass("economy"); //設(shè)置經(jīng)濟(jì)書籍樣式
break;
default:
break;
}
}
}

4.頁(yè)面
<?xml version="1.0" encoding="UTF-8"?>
<jsp:root
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:jsp="http://java.sun.com/JSP/Page"
xmlns:t="http://myfaces.apache.org/tomahawk"
version="2.0">
<jsp:directive.page session="false"
contentType="text/html;charset=UTF-8"
pageEncoding="UTF-8"/>
<jsp:output doctype-public="-//W3C//DTD XHTML 1.1//EN"
doctype-system="http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"
doctype-root-element="html" omit-xml-declaration="true"/>
<f:view>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta content="text/html;charset=UTF-8" http-equiv="Content-Type"/>
<title>特定樣式</title>
<style>
.computers {
background-color: red;
}
.arts {
background-color: white;
}
.economy {
background-color: blue;
}
</style>
</head>
<body>
<h:form>
<t:dataTable id="book"
var="bk"
rowStyleClass="computers"
binding="#{booking.uiData}"
value="#{booking.books}">
<t:column>
<f:facet name="header">
<h:outputText value="編號(hào)"/>
</f:facet>
<h:outputText value="#{bk.id}"></h:outputText>
</t:column>
<t:column>
<f:facet name="header">
<h:outputText value="書名"/>
</f:facet>
<h:outputText value="#{bk.name}"></h:outputText>
</t:column>
<t:column>
<f:facet name="header">
<h:outputText value="類別"/>
</f:facet>
<t:selectOneMenu value="#{bk.type}" displayValueOnly="true" >
<f:selectItems value="#{book.items}"/>
</t:selectOneMenu>
</t:column>
</t:dataTable>
</h:form>
</body>
</html>
</f:view>
</jsp:root>
5.簡(jiǎn)要配置
<managed-bean>
<managed-bean-name>book</managed-bean-name>
<managed-bean-class>net.blogjava.fangshun.book.Book</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>booking</managed-bean-name>
<managed-bean-class>net.blogjava.fangshun.book.BookList</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
6.顯示效果
總結(jié):主要是靠自定義的DataModel對(duì)象,在獲取每一行記錄的開始,來(lái)根據(jù)業(yè)務(wù)為綁定的uiData組件設(shè)置自己的樣式,這樣就可以自由靈活的控制數(shù)據(jù)列表每一行記錄產(chǎn)生時(shí)的狀態(tài)。上面的代碼在jdk1.5下需要myfaces支持,完全測(cè)試通過(guò),希望可以為大家在使用jsf上得到更多的提示和技巧!
方順
fangshun1980@hotmail.com