使用DataModelListener对‘jsf的dataTable组件自定义控制指定行样式的方法 ’的改进
‘jsf的dataTable组件自定义控制指定行样式的方法’ 这篇文章我主要通过覆写DataModel对象的getRowData()方法来控制DataTable每一行的行为,其实还有个标准的方式,也更加优雅,那就是使用DataModelListener,典型的监听事件,jsf内置了数据模型监听机制以便开发者对于数据模型每一行的控制,而且这种监听可以无限增加,使得对每一行控制的方式变成一个个监听对象,非常好用,下面就是更改过得样例:
package
net.blogjava.fangshun.book;
import java.util.List;
import javax.faces.context.FacesContext;
import javax.faces.el.VariableResolver;
import javax.faces.model.DataModelEvent;
import javax.faces.model.DataModelListener;
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);
super.addDataModelListener(new BookListDataModelListener());
}
/** *//**
* 覆写了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;
}
}
class BookListDataModelListener implements DataModelListener {
public void rowSelected(DataModelEvent event) {
// 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)event.getRowData();
if(book != null) {
//根据当前行Book实例的业务特征为HtmlDataTable组件设置渲染行样式
setCurrentRowStyle(table, book.getType());
}
}
}
}
import java.util.List;
import javax.faces.context.FacesContext;
import javax.faces.el.VariableResolver;
import javax.faces.model.DataModelEvent;
import javax.faces.model.DataModelListener;
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);
super.addDataModelListener(new BookListDataModelListener());
}
/** *//**
* 覆写了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;
}
}
class BookListDataModelListener implements DataModelListener {
public void rowSelected(DataModelEvent event) {
// 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)event.getRowData();
if(book != null) {
//根据当前行Book实例的业务特征为HtmlDataTable组件设置渲染行样式
setCurrentRowStyle(table, book.getType());
}
}
}
}
我把监听器BookListDataModelListener作为我的自定义模型的一个内部类来增强业务聚合性,大家在使用的时候可以直接使用一些标准的DataModel,例如ListDataModel等,可以为每个监听器新建一个对象,然后在jsf业务层去实例化调用,不一定要向样例那样放在一起。但是一定要记住,event.getRowData()可能有空值(最后一行的终结处),所以要向样例那样,进行非空判断!