分页加载是采用网上盛传的分页代码完成的。具体的实现还是看代码吧。
/pages/grid/grid.jsp
<%@page contentType="text/html"%> <%@page pageEncoding="UTF-8"%> <%@taglib uri="http://java.sun.com/jsf/core" prefix="f"%> <%@taglib uri="http://java.sun.com/jsf/html" prefix="h"%> <%@taglib uri="http://richfaces.org/rich" prefix="rich"%> <%@taglib uri="http://richfaces.org/a4j" prefix="a4j"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>grid demo</title> <style> .inplace{ border: none; } .hover { color: red; background-color :yellow; } .columns { width: 33%; } .scrollerCell { padding-right: 10px; padding-left: 10px; } .activeRow { background-color:#FFC8B4; } .drgind_wordcut{ padding : 0px 0px 0px 3px; width : 700px; overflow : hidden; float : left; white-space: nowrap; word-spacing : 80px; } </style> </head> <body> <f:view> <div id="top"> <h3>grid demo about sortable、filtable、drag and drop</h3> </div> <rich:dragIndicator id="indicator" styleClass="drgind_wordcut"/> <h:form id="myform"> <h:panelGrid columns="1" columnClasses="top"> <rich:extendedDataTable value="#{personsBean.defaultDataModel}" var="p" id="table" onRowMouseOver="this.style.backgroundColor='#BBFFEE'" onRowMouseOut="this.style.backgroundColor='#FFFFFF'" activeClass="activeRow" width="800px" sortMode="single" selectionMode="single" rows="#{personsBean.rows}" rowKeyVar="row" ajaxKeys="#{personsBean.keys}" > <rich:column sortable="true" sortBy="#{p.id}" width="100px"> <f:facet name="header"> <h:outputText value="Id"/> </f:facet> <a4j:outputPanel id="dragpanel" style="width:20px" layout="block" οnmοusemοve="this.style.cursor='pointer';"> <rich:dragSupport dragIndicator="indicator" dragType="all" dragValue="#{p}"> <rich:dndParam name="label" value="#{p.id} #{p.name} #{p.sex} #{p.age} #{p.address}" /> </rich:dragSupport> <rich:dropSupport acceptedTypes="all" dropValue="#{p}" dropListener="#{eventBean.processDrop}" reRender="table" oncomplete="if(#{personsBean.canOpenMsgPanel==1}) #{rich:component('msgPanel')}.show()"> </rich:dropSupport> <h:outputText value="#{p.id}"/> </a4j:outputPanel> </rich:column> <rich:column width="100px"> <f:facet name="header"> <h:selectBooleanCheckbox immediate="true" id="checkall" value="#{personsBean.checkedAll}" valueChangeListener="#{personsBean.checkAllListener}" οnchange="this.form.submit();"/> </f:facet> <h:selectBooleanCheckbox id="checkone" value="#{p.selected}"/> </rich:column> <rich:column sortable="true" sortBy="#{p.name}" width="100px"> <f:facet name="header"> <h:outputText value="Name"/> </f:facet> <h:outputText value="#{p.name}"/> </rich:column> <rich:column sortable="false" width="100px"> <f:facet name="header"> <h:outputText value="Sex"/> </f:facet> <h:outputText value="#{p.sex}"/> </rich:column> <rich:column sortable="true" sortBy="#{p.age}" width="100px"> <f:facet name="header"> <h:outputText value="Age"/> </f:facet> <rich:inplaceInput layout="block" value="#{p.age}" converterMessage="Age value should be integer. Age at row #{row+1} can't be changed." id="inplace" required="true" requiredMessage="Age at row #{row+1} wasn't filled. Value can't be changed." changedHoverClass="hover" viewHoverClass="hover" viewClass="inplace" changedClass="inplace" selectOnEdit="true" editEvent="onclick" valueChangeListener="#{personsBean.saveInplaceInput}"> <a4j:support event="onviewactivated" reRender="table"/> </rich:inplaceInput> <h:inputHidden value="#{p}"/> </rich:column> <rich:column sortable="false" width="100px"> <f:facet name="header"> <h:outputText value="Address"/> </f:facet> <h:outputText value="#{p.address}"/> </rich:column> <rich:column sortable="true" sortBy="#{p.sort}" width="100px"> <f:facet name="header"> <h:outputText value="Sort"/> </f:facet> <h:outputText value="#{p.sort}"/> </rich:column> <rich:column width="100px"> <f:facet name="header"> <h:outputText value="Actions"/> </f:facet> <a4j:commandLink ajaxSingle="true" id="editlink" oncomplete="#{rich:component('editPanel')}.show()"> <h:graphicImage value="/images/icons/edit.gif" style="border:0"/> <f:setPropertyActionListener value="#{p}" target="#{personsBean.currentItem}" /> <f:setPropertyActionListener value="#{row}" target="#{personsBean.currentRow}" /> </a4j:commandLink> <rich:toolTip for="editlink" value="Edit"/> </rich:column> </rich:extendedDataTable> <rich:datascroller for="table" id="dc1" style="width:800px" page="#{personsBean.scrollerPage}"/> </h:panelGrid> </script> <h:panelGrid columns="3" columnClasses="top,top,top"> <a4j:commandButton value="add" ajaxSingle="true" id="addbutton" oncomplete="#{rich:component('addPanel')}.show()"/> <a4j:commandButton value="edit" id="editbutton" action="#{personsBean.edit}" reRender="msgPanel" oncomplete="if(#{personsBean.canOpenMsgPanel==0})#{rich:component('editPanel')}.show();else if(#{personsBean.canOpenMsgPanel==1})#{rich:component('msgPanel')}.show();"/> <a4j:commandButton value="delete" id="deletebutton" action="#{personsBean.deleteCheck}" reRender="msgPanel,deletePanel" oncomplete="if(#{personsBean.canOpenMsgPanel==0})#{rich:component('deletePanel')}.show();else if(#{personsBean.canOpenMsgPanel==1})#{rich:component('msgPanel')}.show();"/> </h:panelGrid> </h:form> <rich:modalPanel id="addPanel" autosized="true" width="450"> <f:facet name="header"> <h:outputText value="Add New Person" /> </f:facet> <f:facet name="controls"> <h:panelGroup> <h:graphicImage value="/images/modal/close.png" id="hidelink3" styleClass="hidelink"/> <rich:componentControl for="addPanel" attachTo="hidelink3" operation="hide" event="onclick" /> </h:panelGroup> </f:facet> <h:form> <rich:messages style="color:red;"></rich:messages> <h:panelGrid columns="1"> <a4j:outputPanel ajaxRendered="true"> <h:panelGrid columns="2"> <h:outputText value="Name"/> <h:inputText value="#{personsBean.newPerson.name}" label="Name" required="true" immediate="true"/> <h:outputText value="Sex" /> <h:inputText value="#{personsBean.newPerson.sex}" /> <h:outputText value="Age" /> <h:inputText value="#{personsBean.newPerson.age}" label="Age" immediate="true"/> <h:outputText value="Address" /> <h:inputText value="#{personsBean.newPerson.address}" /> </h:panelGrid> <rich:message showSummary="true" showDetail="false" for="Name"/> <rich:message showSummary="true" showDetail="false" for="Age"/> </a4j:outputPanel> <a4j:commandButton value="add" action="#{personsBean.add}" reRender="table" oncomplete="if (#{facesContext.maximumSeverity==null}) #{rich:component('addPanel')}.hide();" /> </h:panelGrid> </h:form> </rich:modalPanel> <rich:modalPanel id="editPanel" autosized="true" width="450"> <f:facet name="header"> <h:outputText value="Edit Current Person" /> </f:facet> <f:facet name="controls"> <h:panelGroup> <h:graphicImage value="/images/modal/close.png" id="hidelink" styleClass="hidelink"/> <rich:componentControl for="editPanel" attachTo="hidelink" operation="hide" event="onclick" /> </h:panelGroup> </f:facet> <h:form> <rich:messages style="color:red;"></rich:messages> <h:panelGrid columns="1"> <a4j:outputPanel ajaxRendered="true"> <h:panelGrid columns="2"> <h:outputText value="Name"/> <h:inputText value="#{personsBean.currentItem.name}" label="Name" required="true" immediate="true"/> <h:outputText value="Sex" /> <h:inputText value="#{personsBean.currentItem.sex}" /> <h:outputText value="Age" /> <h:inputText value="#{personsBean.currentItem.age}" label="Age" immediate="true"/> <h:outputText value="Address" /> <h:inputText value="#{personsBean.currentItem.address}" /> </h:panelGrid> <rich:message showSummary="true" showDetail="false" for="Name"/> <rich:message showSummary="true" showDetail="false" for="Age"/> </a4j:outputPanel> <a4j:commandButton value="Save" action="#{personsBean.save}" reRender="table" oncomplete="if (#{facesContext.maximumSeverity==null}) #{rich:component('editPanel')}.hide();" /> </h:panelGrid> </h:form> </rich:modalPanel> <rich:modalPanel id="deletePanel" autosized="true" width="200"> <f:facet name="header"> <h:outputText value="Delete this Person from table?" style="padding-right:15px;" /> </f:facet> <f:facet name="controls"> <h:panelGroup> <h:graphicImage value="/images/modal/close.png" styleClass="hidelink" id="hidelink2" /> <rich:componentControl for="deletePanel" attachTo="hidelink2" operation="hide" event="onclick" /> </h:panelGroup> </f:facet> <h:form> <table width="100%"> <tbody> <tr> <td colspan="2" align="center"> <h:outputText value="#{personsBean.msg}" escape="false"/> </td> </tr> <tr> <td align="center" width="50%"> <a4j:commandButton value="Yes" ajaxSingle="true" action="#{personsBean.deleteSelected}" reRender="table" oncomplete="#{rich:component('deletePanel')}.hide();" /> </td> <td align="center" width="50%"> <a4j:commandButton value="Cancel" οnclick="#{rich:component('deletePanel')}.hide();return false;" /> </td> </tr> </tbody> </table> </h:form> </rich:modalPanel> <a4j:status onstart="#{rich:component('wait')}.show()" onstop="#{rich:component('wait')}.hide()"/> <rich:modalPanel id="wait" autosized="true" width="200" height="120" moveable="false" resizeable="false"> <f:facet name="header"> <h:outputText value="Processing"/> </f:facet> <h:outputText value="Wait Please..."/> </rich:modalPanel> <rich:messages></rich:messages> <rich:modalPanel id="msgPanel" autosized="true" width="200"> <f:facet name="header"> <h:outputText value="msg" style="padding-right:15px;" /> </f:facet> <f:facet name="controls"> <h:panelGroup> <h:graphicImage value="/images/modal/close.png" styleClass="hidelink" id="msghidelink" /> <rich:componentControl for="msgPanel" attachTo="msghidelink" operation="hide" event="onclick" /> </h:panelGroup> </f:facet> <table width="200px"> <tbody> <tr> <td align="center"> <h:outputText value="#{personsBean.msg}" escape="false"/> </td> </tr> <tr> <td align="center" width="50%"> <a4j:commandButton value="Ok" οnclick="#{rich:component('msgPanel')}.hide();return false;" /> </td> </tr> </tbody> </table> </rich:modalPanel> </f:view> </body> </html>
package demo下的hibernate.cfg.xml
<?xml version='1.0' encoding='utf-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url">jdbc:mysql://127.0.0.1:3306/richfaces_demo</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">mysql51</property> <property name="hibernate.connection.pool_size">10</property> <property name="show_sql">true</property> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <mapping resource="/demo/grid/Person.hbm.xml"/> </session-factory> </hibernate-configuration>
package demo.util下的class:
package demo.util;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.hibernate.cfg.Configuration;
import org.hibernate.SessionFactory;
import javax.servlet.ServletContextListener;
/**
*
* @author SailingLee
*/
public class DBUtil implements ServletContextListener{
private static SessionFactory sf = null;
public DBUtil() {
}
public void contextInitialized(ServletContextEvent servletContextEvent) {
sf = new Configuration().configure("/demo/hibernate.cfg.xml").buildSessionFactory();
}
public void contextDestroyed(ServletContextEvent servletContextEvent) {
sf.close();
}
public static SessionFactory getSf() {
return sf;
}
}
package demo.phase下的class:
package demo.phase;
import java.util.Map;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;
public class PostbackPhaseListener implements PhaseListener {
public static final String POSTBACK_ATTRIBUTE_NAME = PostbackPhaseListener.class.getName();
public void afterPhase(PhaseEvent event) {
}
public void beforePhase(PhaseEvent event) {
FacesContext facesContext = event.getFacesContext();
Map requestMap = facesContext.getExternalContext().getRequestMap();
requestMap.put(POSTBACK_ATTRIBUTE_NAME, Boolean.TRUE);
}
public PhaseId getPhaseId() {
return PhaseId.APPLY_REQUEST_VALUES;
}
public static boolean isPostback() {
FacesContext facesContext = FacesContext.getCurrentInstance();
if (facesContext != null) {
ExternalContext externalContext = facesContext.getExternalContext();
if (externalContext != null) {
return Boolean.TRUE.equals(
externalContext.getRequestMap().get(POSTBACK_ATTRIBUTE_NAME));
}
}
return false;
}
}
package demo.grid下的class和*.hbm.xml:
package demo.grid;
import org.richfaces.component.Dropzone;
import org.richfaces.event.DropEvent;
import org.richfaces.event.DropListener;
import org.richfaces.event.extdt.ExtTableSortListener;
import org.richfaces.event.extdt.ExtTableSortEvent;
public class EventBean implements DropListener,ExtTableSortListener {
private PersonsBean personsBean;
/**
* 拖动操作的监听
*/
public void processDrop(DropEvent dropEvent) {
Dropzone dropzone = (Dropzone) dropEvent.getComponent();
personsBean.move(dropEvent.getDragValue(), dropzone.getDropValue());
}
/**
* 排序操作的监听
*/
public void processSort(ExtTableSortEvent sortEvent) {
personsBean.setSortedState(1);
}
public PersonsBean getPersonsBean() {
return personsBean;
}
public void setPersonsBean(PersonsBean personsBean) {
this.personsBean = personsBean;
}
}
/*
* Person.java
*
*/
package demo.grid;
import java.io.Serializable;
public class Person implements Serializable{
private int id;
private String name;
private String sex;
private int age;
private String address;
private int sort;
private boolean selected;
/** Creates a new instance of PersonBean */
public Person() {
}
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 String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
/**
* @return the sort
*/
public int getSort() {
return sort;
}
/**
* @param sort the sort to set
*/
public void setSort(int sort) {
this.sort = sort;
}
public boolean isSelected() {
return selected;
}
public void setSelected(boolean selected) {
this.selected = selected;
}
}
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="demo.grid"> <class name="Person" table="person"> <id column="id" name="id"> <generator class="native"/> </id> <property name="name" not-null="true" type="java.lang.String"/> <property name="sex" type="java.lang.String"/> <property name="age"/> <property name="address" type="java.lang.String"/> <property name="sort" not-null="true"/> </class> </hibernate-mapping>
/*
* PersonsBean.java
*
*/
package demo.grid;
import demo.util.DBUtil;
import demo.page.DataPage;
import demo.page.PagedListDataModel;
import demo.page.PageListBaseBean;
import java.math.BigInteger;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.event.ValueChangeEvent;
import org.hibernate.SessionFactory;
import org.hibernate.Session;
import org.hibernate.Query;
public class PersonsBean extends PageListBaseBean {
private int rows = 3;//每页显示的记录数(行数)
private SessionFactory sf;
private int scrollerPage = 1;//滚动页码
private Person currentItem = new Person();//当前操作的记录
private Person newPerson = new Person();//添加的新记录
private Set<Integer> keys = new HashSet<Integer>();//row keys are updated after a ajax request
private int sortedState = 0;//0:not sort 1:sorted
private String msg;//msgPanel中显示的提示信息
private int canOpenMsgPanel = -1;//1:可打开 0:不可打开 (是否可以打开msgPanel的标志)
private boolean checkedAll;//checkall标志:是否全选
/** Creates a new instance of PersonsBean */
public PersonsBean() {
sf = DBUtil.getSf();//获取db sessionfactory实例
//exTable = new UIExtendedDataTable();
}
public int getRows() {
return rows;
}
public void setRows(int rows) {
this.rows = rows;
}
public int getScrollerPage() {
return scrollerPage;
}
public void setScrollerPage(int scrollerPage) {
this.scrollerPage = scrollerPage;
}
/**
* 拖动表格中的行,表格内拖动,改变行顺序
*
*/
public void move(Object dragObj, Object dropObj) {
if(this.sortedState == 1) {
//若拖动操作前有通过表头进行升序或降序排序操作,则拖动操作应被禁止(此功能尚未实现)
this.setCanOpenMsgPanel(1);
this.setMsg("You can not drag and drop the items,for you have sorted them by click column!");
return;
}
Person dragPerson = (Person) dragObj;
Person dropPerson = (Person) dropObj;
int dropPersonSort = dropPerson.getSort();
int dragPersonSort = dragPerson.getSort();
if (dragPersonSort == -1 || dropPersonSort == -1 || dropPersonSort == dragPersonSort) {
return;
}
//拖动操作引起的更新sort域
String sql = "select max(sort) from Person where sort < :dropPersonSort";
Session ss = sf.openSession();
Object o = ss.createQuery(sql).setInteger("dropPersonSort", dropPersonSort).uniqueResult();
if (null != o) {
int dropUpPersonSort = ((Integer) o).intValue();
if ((dropPersonSort - dropUpPersonSort) < 2) {
//resort "sort" field in table "person"
this.resortAllPersonSort();//重新分配数据库中所有记录的sort
super.defaultDataModel.refresh();
ss.close();
return;
}
int newSort = dropUpPersonSort + 1;
dragPerson.setSort(newSort);
ss.beginTransaction().begin();
ss.update(dragPerson);
ss.flush();
ss.beginTransaction().commit();
ss.close();
super.defaultDataModel.refresh();
}
}
private void resortAllPersonSort() {
Session ss = sf.openSession();
String sql = "from Person";
List list = ss.createQuery(sql).list();
if (null != list) {
int sort = 0;
ss.beginTransaction().begin();
for (int i = 0; i < list.size(); i++) {
Person p = (Person)list.get(i);
sort += 100;
p.setSort(sort);
ss.flush();
ss.evict(p);
}
ss.beginTransaction().commit();
ss.close();
}
}
//pagination//
public PagedListDataModel getDefaultDataModel() {
if (defaultDataModel == null) {
super.setPageSize(rows);//为分页操作设置每页显示记录数
defaultDataModel = new PagedListDataModel(pageSize) {
public DataPage fetchPage(int startRow, int pageSize) {
// call enclosing managed bean method to fetch the data
Session ss = sf.openSession();
String sql = "from Person order by sort asc";
Query q = ss.createQuery(sql);
q.setFirstResult(startRow);
q.setMaxResults(pageSize);
List list = q.list();
sql = "select count(*) from person";
Object o = ss.createSQLQuery(sql).uniqueResult();
int count = -1;
if (null != o) {
count = ((BigInteger) o).intValue();
}
ss.close();
return new DataPage(count, startRow, list);
}
};
}
return defaultDataModel;
}
//
/**
* 编辑后的保存操作
*/
public void save() {
Session ss = sf.openSession();
ss.beginTransaction().begin();
ss.update(this.currentItem);
ss.flush();
ss.beginTransaction().commit();
ss.close();
super.defaultDataModel.refresh();
}
/**
* 删除操作前检查选中的记录
*/
public void deleteCheck(){
Object o = defaultDataModel.getWrappedData();
if(null != o){
List list = (List)o;
int size = this.selectObjSize(list);
if(size == 0){
this.setMsg("You must select one or more!Please check it!");
this.setCanOpenMsgPanel(1);
}else{
this.setMsg("You've selected <font color='red'><b>" + size + "</b></font> items! Are you sure delete selected items?");
this.setCanOpenMsgPanel(0);
}
}
}
/**
* 删除选中的记录
*/
public void deleteSelected(){
Object o = defaultDataModel.getWrappedData();
if(null != o){
List list = (List)o;
Session ss = sf.openSession();
ss.beginTransaction().begin();
for(int i=0;i<list.size();i++){
Person p = (Person)list.get(i);
if(p.isSelected()){
ss.delete(p);
}
}
ss.beginTransaction().commit();
ss.flush();
ss.close();
this.setCanOpenMsgPanel(0);
super.defaultDataModel.refresh();
}
}
/**
* 添加记录时,获取新的sort
*
*/
private int getNewSort(){
Session ss = sf.openSession();
String sql = "select max(sort) from Person";
Object o = ss.createQuery(sql).uniqueResult();
int sort = -1;
if (null != o) {
sort = ((Integer) o).intValue() + 100;
}
ss.close();
return sort;
}
/**
* 添加并保存新记录
*
*/
public void add() {
Session ss = sf.openSession();
this.newPerson.setSort(getNewSort());
ss.beginTransaction().begin();
ss.save(this.newPerson);
ss.flush();
ss.beginTransaction().commit();
ss.close();
this.newPerson = new Person();
super.defaultDataModel.refresh();
}
/**
* 在行内修改记录,并更新修改后的数据
*/
public void saveInplaceInput(ValueChangeEvent e) {
int oldValue = ((Integer) e.getOldValue()).intValue();
int newValue = ((Integer) e.getNewValue()).intValue();
if (oldValue == newValue) {
return;
}
List list = e.getComponent().getParent().getChildren();
for (int i = 0; i < list.size(); i++) {
UIComponent c = (UIComponent) list.get(i);
Object o = c.getValueExpression("value").getValue(FacesContext.getCurrentInstance().getELContext());
if (o instanceof Person) {
Person p = (Person) o;
p.setAge(newValue);
Session ss = sf.openSession();
ss.beginTransaction().begin();
ss.update(p);
ss.flush();
ss.beginTransaction().commit();
ss.close();
super.defaultDataModel.refresh();
}
}
}
/**
* 修改记录前的选中检查
*/
public void edit(){
Object o = defaultDataModel.getWrappedData();
if(null != o){
List list = (List)o;
int size = this.selectObjSize(list);
if(size == 0){
this.setMsg("Please select one!");
this.setCurrentItem(null);
this.setCanOpenMsgPanel(1);
return;
}else if(size > 1){
this.setMsg("You can only select one!Please check it!");
this.setCurrentItem(null);
this.setCanOpenMsgPanel(1);
return;
}
for(int i=0;i<list.size();i++){
Person p = (Person)list.get(i);
if(p.isSelected()){
this.setCurrentItem(p);
this.setCanOpenMsgPanel(0);
return;
}
}
}
}
/**
* 获取选中的记录数
*/
public int selectObjSize(List list){
int size = 0;
for(int i=0;i<list.size();i++){
Person p = (Person)list.get(i);
if(p.isSelected())
size++;
}
return size;
}
/**
* 全选操作的监听,为内存中对应当前页的记录更新选中状态
*/
public void checkAllListener(ValueChangeEvent e){
boolean flag = ((Boolean)e.getNewValue()).booleanValue();
Object o = super.defaultDataModel.getWrappedData();
if(null != o){
List list = (List)o;
for(int i=0;i<list.size();i++){
Person p = (Person)list.get(i);
p.setSelected(flag);
}
FacesContext.getCurrentInstance().renderResponse();//这里需要显示调用呈现响应
}
}
//
public Person getCurrentItem() {
return currentItem;
}
public void setCurrentItem(Person currentItem) {
this.currentItem = currentItem;
}
public Set<Integer> getKeys() {
return keys;
}
public void setKeys(Set<Integer> keys) {
this.keys = keys;
}
public Person getNewPerson() {
return newPerson;
}
public void setNewPerson(Person newPerson) {
this.newPerson = newPerson;
}
public int getSortedState() {
return sortedState;
}
public void setSortedState(int sortedState) {
this.sortedState = sortedState;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public int getCanOpenMsgPanel() {
return canOpenMsgPanel;
}
public void setCanOpenMsgPanel(int canOpenMsgPanel) {
this.canOpenMsgPanel = canOpenMsgPanel;
}
public boolean isCheckedAll() {
return checkedAll;
}
public void setCheckedAll(boolean checkedAll) {
this.checkedAll = checkedAll;
}
}
/WEB-INF/下的xml
<?xml version='1.0' encoding='UTF-8'?> <!DOCTYPE faces-config PUBLIC "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.1//EN" "http://java.sun.com/dtd/web-facesconfig_1_1.dtd"> <!-- =========== FULL CONFIGURATION FILE ================================== --> <faces-config> <!--(down) add by SailingLee about grid demo--> <managed-bean> <managed-bean-name>person</managed-bean-name> <managed-bean-class>demo.grid.Person</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>personsBean</managed-bean-name> <managed-bean-class>demo.grid.PersonsBean</managed-bean-class> <managed-bean-scope>session</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>eventBean</managed-bean-name> <managed-bean-class>demo.grid.EventBean</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> <managed-property> <property-name>personsBean</property-name> <property-class>demo.grid.PersonsBean</property-class> <value>#{personsBean}</value> </managed-property> </managed-bean> <!--(up) add by SailingLee about grid demo--> <factory> <application-factory>org.richfaces.ui.application.StateApplicationFactory</application-factory> </factory> <lifecycle> <phase-listener>demo.phase.PostbackPhaseListener</phase-listener> </lifecycle> </faces-config>
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <!-- RichFaces Skin --> <context-param> <param-name>org.richfaces.SKIN</param-name> <param-value>blueSky</param-value> </context-param> <!-- Faces Servlet --> <context-param> <param-name>javax.faces.STATE_SAVING_METHOD</param-name> <param-value>client</param-value> </context-param> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup>-1</load-on-startup> </servlet> <!-- Faces Servlet Mapping --> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>*.jsf</url-pattern> </servlet-mapping> <!-- RichFaces Filter --> <filter> <display-name>RichFaces Filter</display-name> <filter-name>richfaces</filter-name> <filter-class>org.ajax4jsf.Filter</filter-class> </filter> <filter-mapping> <filter-name>richfaces</filter-name> <servlet-name>Faces Servlet</servlet-name> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> <dispatcher>INCLUDE</dispatcher> </filter-mapping> <session-config> <session-timeout> 30 </session-timeout> </session-config> <welcome-file-list> <welcome-file> index.jsp </welcome-file> </welcome-file-list> <listener> <listener-class>demo.util.DBUtil</listener-class> </listener> </web-app>
package demo.page下的class:
/**
* A simple class that represents a "page" of data out of a longer set, ie a
* list of objects together with info to indicate the starting row and the full
* size of the dataset. EJBs can return instances of this type when returning
* subsets of available data.
*/
package demo.page;
import java.util.List;
public class DataPage {
/** *//**
* 将需要的页的数据封装到一个DataPage中去, 这个类表示了我们需要的一页的数据,<br>
* 里面包含有三个元素:datasetSize,startRow,和一个用于表示具体数据的List。<br>
* datasetSize表示了这个记录集的总条数,查询数据的时候,使用同样的条件取count即可,<br>
* startRow表示该页的起始行在数据库中所有记录集中的位置
*/
private int datasetSize;
private int startRow;
private List data;
/** *//**
*
* @param datasetSize
* 数据集大小
* @param startRow
* 起始行
* @param data
* 数据list
*/
public DataPage(int datasetSize, int startRow, List data) {
this.datasetSize = datasetSize;
this.startRow = startRow;
this.data = data;
}
/** *//**
*
* @return
*/
public int getDatasetSize() {
return datasetSize;
}
public int getStartRow() {
return startRow;
}
/** *//**
*
* @return 已填充好的数据集
*/
public List getData() {
return data;
}
}
/*
* PageListBaseBean.java
*/
package demo.page;
/*使用方法参考:
public class User extends PageListBaseBean
{
@Override
public PagedListDataModel getDefaultDataModel()
{
if ( defaultDataModel == null ) {
defaultDataModel = new PagedListDataModel(pageSize)
{
public DataPage fetchPage(int startRow, int pageSize)
{
// call enclosing managed bean method to fetch the data
CarBeanDAO dao = new CarBeanDAO();
String sql = "from CarBean model order by model.id desc";
Query query = EntityManagerHelper.createQuery(sql);
query.setFirstResult(startRow);
query.setMaxResults(pageSize);
List list = query.getResultList();
Query q = EntityManagerHelper.createQuery("select count(*) from CarBean");
return new DataPage(Integer.parseInt(q.getSingleResult().toString()), startRow, list);
}
};
}
return defaultDataModel;
}
}
* 如需添加多个分页功能,请自定义PagedListDataModel变量和实现相关getXXXDataModel方法
*/
/** *//**
* TODO 带分页功能的基类
*
* @author <a href="mailto:tianlu@jsecode.com">TianLu</a>
* @version $Rev$ <br>
* $Id$
*/
public abstract class PageListBaseBean {
/** *//**
* 当前页码,跟dataSroller的page属性绑定
*/
protected int scrollerPage = 1;
/** *//**
* 当前页面大小
*/
protected int pageSize = 10;
/** *//**
* 默认数据模型,如果你有多个数据集需要分页,请自定义PagedListDataModel和相应的getDataModel方法
*/
protected PagedListDataModel defaultDataModel;
public int getScrollerPage() {
return scrollerPage;
}
public void setScrollerPage(int scrollerPage) {
this.scrollerPage = scrollerPage;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public abstract PagedListDataModel getDefaultDataModel();
}
/**
* A special type of JSF DataModel to allow a datatable and datascroller to page
* through a large set of data without having to hold the entire set of data in
* memory at once.
* <p>
* Any time a managed bean wants to avoid holding an entire dataset, the managed
* bean should declare an inner class which extends this class and implements
* the fetchData method. This method is called as needed when the table requires
* data that isn't available in the current data page held by this object.
* <p>
* This does require the managed bean (and in general the business method that
* the managed bean uses) to provide the data wrapped in a DataPage object that
* provides info on the full size of the dataset.
*/
package demo.page;
import java.util.List;
import javax.faces.model.DataModel;
/** *//**
*
* TODO 分页所使用的类
*
* @author <a href="mailto:tianlu@jsecode.com">TianLu</a>
* @version $Rev$ <br>
* $Id$
*/
/**//* 使用方法:
* 前台的功能模块Bean(例如User)中继承PageListBaseBean类,可根据您的需要进行相应修改
* 前台控件像这样使用
* <rich:dataTable id="carList" width="483" columnClasses="col" rows="#{user.pageSize}"
value="#{user.defaultDataModel}" var="car">
<f:facet name="header">
<rich:columnGroup>
<h:column>
<h:outputText styleClass="headerText" value="Name" />
</h:column>
<h:column>
<h:outputText styleClass="headerText" value="Decription" />
</h:column>
<h:column>
<h:outputText styleClass="headerText" value="Base Price" />
</h:column>
<h:column>
<h:outputText styleClass="headerText" value="Time" />
</h:column>
<h:column>
<h:outputText styleClass="headerText" value="操作" />
</h:column>
</rich:columnGroup>
</f:facet>
<h:column>
<h:outputText value="#{car.name}" />
</h:column>
<h:column>
<h:outputText value="#{car.description}" />
</h:column>
<h:column>
<h:outputText value="#{car.baseprice}" />
</h:column>
<h:column>
<h:outputText value="#{car.timestamp}" />
</h:column>
<h:column>
<h:commandLink action="#{user.delete}" value="删除" >
<f:param name="id" value="#{car.id}"/>
</h:commandLink>
</h:column>
</rich:dataTable>
<rich:datascroller for="carList" id="dc1"
style="width:483px" page="#{user.scrollerPage}"/>*/
/**//*
* 进行删除等操作后会立即改变列表项并且返回列表页的,请调用本类的refresh方法刷新当前页面
* 使用方法:
* dao.delete(bean);
* dataModel.refresh();
*/
public abstract class PagedListDataModel extends DataModel {
int pageSize;
int rowIndex;
DataPage page;
/** *//**
* Create a datamodel that pages through the data showing the specified
* number of rows on each page.
*/
public PagedListDataModel(int pageSize) {
super();
this.pageSize = pageSize;
this.rowIndex = -1;
this.page = null;
}
/** *//**
* Not used in this class; data is fetched via a callback to the fetchData
* method rather than by explicitly assigning a list.
*/
public void setWrappedData(Object o) {
if (o instanceof DataPage) {
this.page = (DataPage) o;
} else {
throw new UnsupportedOperationException(" setWrappedData ");
}
}
public int getRowIndex() {
return rowIndex;
}
/** *//**
* Specify what the "current row" within the dataset is. Note that the
* UIData component will repeatedly call this method followed by getRowData
* to obtain the objects to render in the table.
*/
public void setRowIndex(int index) {
rowIndex = index;
}
/** *//**
* Return the total number of rows of data available (not just the number of
* rows in the current page!).
*/
public int getRowCount() {
return getPage().getDatasetSize();
}
/** *//**
* Return a DataPage object; if one is not currently available then fetch
* one. Note that this doesn't ensure that the datapage returned includes
* the current rowIndex row; see getRowData.
*/
private DataPage getPage() {
if (page != null) {
return page;
}
int rowIndex = getRowIndex();
int startRow = rowIndex;
if (rowIndex == -1) {
// even when no row is selected, we still need a page
// object so that we know the amount of data available.
startRow = 0;
} // invoke method on enclosing class
page = fetchPage(startRow, pageSize);
return page;
}
/** *//**
* Return the object corresponding to the current rowIndex. If the DataPage
* object currently cached doesn't include that index then fetchPage is
* called to retrieve the appropriate page.
*/
public Object getRowData() {
if (rowIndex < 0) {
throw new IllegalArgumentException(
" Invalid rowIndex for PagedListDataModel; not within page ");
} // ensure page exists; if rowIndex is beyond dataset size, then
// we should still get back a DataPage object with the dataset size
// in it
if (page == null) {
page = fetchPage(rowIndex, pageSize);
}
int datasetSize = page.getDatasetSize();
int startRow = page.getStartRow();
int nRows = page.getData().size();
int endRow = startRow + nRows;
if (rowIndex >= datasetSize) {
throw new IllegalArgumentException(" Invalid rowIndex ");
}
if (rowIndex < startRow) {
page = fetchPage(rowIndex, pageSize);
startRow = page.getStartRow();
} else if (rowIndex >= endRow) {
page = fetchPage(rowIndex, pageSize);
startRow = page.getStartRow();
}
return page.getData().get(rowIndex - startRow);
}
public Object getWrappedData() {
return page.getData();
}
/** *//**
* Return true if the rowIndex value is currently set to a value that
* matches some element in the dataset. Note that it may match a row that is
* not in the currently cached DataPage; if so then when getRowData is
* called the required DataPage will be fetched by calling fetchData.
*/
public boolean isRowAvailable() {
DataPage page = getPage();
if (page == null) {
return false;
}
int rowIndex = getRowIndex();
if (rowIndex < 0) {
return false;
} else if (rowIndex >= page.getDatasetSize()) {
return false;
} else {
return true;
}
}
/** *//**
* Method which must be implemented in cooperation with the managed bean
* class to fetch data on demand.
*/
public abstract DataPage fetchPage(int startRow, int pageSize);
/** *//**
* 进行删除等操作后会立即改变列表项并且返回列表页的,请调用此方法,用于刷新列表。
*/
public void refresh() {
if (this.page != null) {
this.page = null;
getPage();
}
}
}
使用到的类库见图片附件:lib.jpg