分页加载是采用网上盛传的分页代码完成的。具体的实现还是看代码吧。
/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" onmousemove="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}" onchange="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" onclick="#{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" onclick="#{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:[email protected]">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:[email protected]">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