richfaces3.3.1实现表格的行拖动、分页加载等功能

分页加载是采用网上盛传的分页代码完成的。具体的实现还是看代码吧。

/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

你可能感兴趣的:(sql,Hibernate,bean,servlet,Richfaces)