征服jsf

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  6 随笔 :: 0 文章 :: 27 评论 :: 0 Trackbacks
     HtmlDataTable组件属于UIData家族的HTML数据列表实现,组件中提供了rowStyleClass等方法来控制行的显示,,如果你在rowStyleClass中加入两个样式类,并使用逗号分开,那么渲染的每一行会交替使用这两个样式类进行显示,同理多个样式类也会循环交替显示。但是如果我想根据业务的情况具体指定某行显示成特定的样式,HtmlDataTable就 无能为力了,然而这种业务又很常见,比如我想高亮显示列表中时间过期的行等等......
    下面是一个例子,显示了我的藏书列表,我想让计算机类书籍的行使用红色背景,文学类书籍的行使用白色背景,经济学类书籍的行使用蓝色列表。
     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.显示效果
编号 书名 类别
15 book_15 计算机类
30 book_30 计算机类
43 book_43 文学类
16 book_16 文学类
31 book_31 文学类
48 book_48 计算机类
32 book_32 经济学类
34 book_34 文学类
41 book_41 经济学类
1 book_1 文学类
0 book_0 计算机类
总结:主要是靠自定义的DataModel对象,在获取每一行记录的开始,来根据业务为绑定的uiData组件设置自己的样式,这样就可以自由灵活的控制数据列表每一行记录产生时的状态。上面的代码在jdk1.5下需要myfaces支持,完全测试通过,希望可以为大家在使用jsf上得到更多的提示和技巧!
                                                                                                                              方顺 fangshun1980@hotmail.com
posted on 2007-09-14 15:48 方顺 阅读(3606) 评论(2)  编辑  收藏 所属分类: jsf

评论

# re: jsf的dataTable组件自定义控制指定行样式的方法 2007-09-15 07:59 鱼肠剑
确实不错.是个好想法.记下了.  回复  更多评论
  

# re: jsf的dataTable组件自定义控制指定行样式的方法 2016-03-10 17:48 dundun
@鱼肠剑
问题解决了吗? jsf 组件自定义控制指定行样式的方法  回复  更多评论
  


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


网站导航: