HtmlDataTable组件属于UIData家族的HTML数据列表实现,组件中提供了rowStyleClass等方法来控制行的显示,,如果你在rowStyleClass中加入两个样式类,并使用逗号分开,那么渲染的每一行会交替使用这两个样式类进行显示,同理多个样式类也会循环交替显示。但是如果我想根据业务的情况具体指定某行显示成特定的样式,HtmlDataTable就 无能为力了,然而这种业务又很常见,比如我想高亮显示列表中时间过期的行等等......
下面是一个例子,显示了我的藏书列表,我想让计算机类书籍的行使用红色背景,文学类书籍的行使用白色背景,经济学类书籍的行使用蓝色列表。
1.首先是Book模型
2. book的列表模型
3. 自定义的数据模型
4.页面
5.简要配置
6.显示效果
总结:主要是靠自定义的DataModel对象,在获取每一行记录的开始,来根据业务为绑定的uiData组件设置自己的样式,这样就可以自由灵活的控制数据列表每一行记录产生时的状态。上面的代码在jdk1.5下需要myfaces支持,完全测试通过,希望可以为大家在使用jsf上得到更多的提示和技巧!
下面是一个例子,显示了我的藏书列表,我想让计算机类书籍的行使用红色背景,文学类书籍的行使用白色背景,经济学类书籍的行使用蓝色列表。
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; //书籍编号
- 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; //计算机类
- public static final int ART_BOOK = 2; //文学类
- public static final int ECONOMY_BOOK = 3; //经济类
- private List<SelectItem> items;
- /** *//**
- * 为下拉菜单提供模拟数据
- * @return
- */
- public List<SelectItem> getItems() {
- if(items == null) {
- items = new ArrayList<SelectItem>();
- SelectItem item = new SelectItem();
- item.setLabel("计算机类");
- item.setValue(COMPUTER_BOOK);
- items.add(item);
- item = new SelectItem();
- item.setLabel("文学类");
- item.setValue(ART_BOOK);
- items.add(item);
- item = new SelectItem();
- item.setLabel("经济学类");
- 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作为数据源的UIData组件,常使用的是HtmlDataTable这个实现组件
- // 这样可以通过调用BookList模型来间接访问到HtmlDataTable组件,以便控制组件
- // 内部的状态
- private UIData uiData;
- private ListDataModel books;
- //UIData组件的values属性可以直接读取DataModel家族的对象
- //这里没有返回Collection集合对象,是为了在自定义的BookListDataModel
- //对象中控制UIData组件的状态
- 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;
- }
- /** *//**
- * 创建模拟数据
- * @return List<Book>
- */
- public List<Book> createBooks() {
- //使用HashMap是为了打乱数据的排序
- 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. 自定义的数据模型
- 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对象的getRowData方法,每次uiData组件从模型列表获取新一行记录
- * 的时候,是从这里发起的,所以在这里可以通过获取uiData组件,来对uiData组件的状态进行
- * 调整。目前的调整就是根据业务的需要对uiData组件的每一行样式进行特殊指定。
- */
- @Override
- public Object getRowData() {
- // TODO Auto-generated method stub
- /
- //通过变量解析获取request scope中的BookList列表模型
- FacesContext facesContext = FacesContext.getCurrentInstance();
- VariableResolver vr = facesContext.getApplication().getVariableResolver();
- BookList bookList = (BookList)vr.resolveVariable(facesContext, "booking");
- /
- //间接得到绑定BookList列表模型的uiData组件,并向下转型成HtmlDataTable(myfaces扩展类型)组件
- HtmlDataTable table = (HtmlDataTable)bookList.getUiData();
- //获取当前行的Book实例
- Book book = (Book)super.getRowData();
- //根据当前行Book实例的业务特征为HtmlDataTable组件设置渲染行样式
- setCurrentRowStyle(table, book.getType());
- return book;
- }
- /** *//**
- * 根据不同的类型,设置当前行的样式
- * @param table
- * @param type
- */
- private void setCurrentRowStyle(HtmlDataTable table, int type) {
- switch (type) {
- case Book.COMPUTER_BOOK:
- //System.out.println("computers");
- table.setRowStyleClass("computers"); //设置计算机书籍样式
- break;
- case Book.ART_BOOK:
- //System.out.println("arts");
- table.setRowStyleClass("arts"); //设置文学书籍样式
- break;
- case Book.ECONOMY_BOOK:
- //System.out.println("C");
- table.setRowStyleClass("economy"); //设置经济书籍样式
- break;
- default:
- break;
- }
- }
- }
4.页面
- <?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="编号"/>
- </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.简要配置
- <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.显示效果
总结:主要是靠自定义的DataModel对象,在获取每一行记录的开始,来根据业务为绑定的uiData组件设置自己的样式,这样就可以自由灵活的控制数据列表每一行记录产生时的状态。上面的代码在jdk1.5下需要myfaces支持,完全测试通过,希望可以为大家在使用jsf上得到更多的提示和技巧!