`

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: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

  • 大小: 82.5 KB
4
0
分享到:
评论

相关推荐

    richfaces3.3.1官方demo的源代码

    RichFaces 3.3.1是该框架的一个重要版本,它包含了各种增强的AJAX功能,如异步数据处理、动态组件渲染和事件处理等。这个版本的亮点在于其强大的组件库,包括表格、树形结构、日历、对话框等,这些都极大地提高了...

    richfaces3.3.1中树的节点的拖动

    总的来说,"richfaces3.3.1中树的节点的拖动"是RichFaces为开发者提供的一种强大且易于使用的交互功能。理解其实现原理和使用方法,能帮助我们在构建富客户端应用程序时提供更加灵活和友好的用户界面。通过实践和...

    jsf 1.2 myfaces1.2.7 richfaces3.3.1 facelets1.2 所有的最新包

    RichFaces 3.3.1版本包含了诸如数据网格、对话框、滑块、日历等高级组件,大大增强了JSF应用的用户体验。它还提供了事件驱动的Ajax支持,允许部分页面刷新,而无需刷新整个页面。 **Facelets 1.2** 是JSF的视图层...

    richfaces-ui-3.3.1.GA-bin

    2. 组件库:RichFaces提供了一套强大的组件集合,包括数据表格、图表、日历、树形结构等,这些组件都具有良好的AJAX支持,可轻松实现复杂的用户界面。 3. 皮肤和主题: RichFaces支持自定义皮肤和主题,允许开发者...

    richfaces 3.3.1GA 源代码

    包括三个jar: richfaces-api-3.3.1.GA-sources.jar richfaces-impl-3.3.1.GA-sources.jar richfaces-ui-3.3.1.GA-sources.jar

    richfaces-3.3:Nuxeo 所需补丁的 Richfaces 3.3.1.GA 源的分支

    Nuxeo 所需补丁的 Richfaces 3.3.1.GA 源的分支。 原始资源可以在这里下载: 如何构建 运行mvn clean install 。 该构建适用于 Maven 2.2.1。 结果罐子: richfaces-impl-3.3.1.GA-NX8-SNAPSHOT.jar richfaces-ui...

    richfaces最新版3.3.1.CR3demo

    richfaces Demo 最新版3.3.1.CR3下载,直接放在tomcat上即可运行,访问网址:http://localhost:8080/richfaces-demo-3.3.1.CR3-tomcat6

    richfaces-demo-3.3.1.GA-tomcat6

    richfaces-demo-3.3.1.GA-tomcat6 最新发布的一个版本 来源于Jboss:如果大家需要其他的版本可以去下载

    jsf中richfaces的jar包及源文件等

    **RichFaces** 是一个基于JSF的开源扩展库,它为JSF提供了一系列高级的富客户端组件和Ajax功能。RichFaces的目标是提升用户体验,通过提供富交互性和动态更新能力,使得Web应用更加生动和响应迅速。 **Jar包**...

    richfaces jar

    richfaces环境搭建所需要的jar richfaces-api-3.3.1.GA.jar richfaces-impl-3.3.1.GA.jar richfaces-ui-3.3.1.GA.jar 希望对搭建有帮助

    使用richfaces 实现tree

    5. **实现扩展功能**:RichFaces的`&lt;rich:tree&gt;`组件提供了许多扩展功能,比如节点展开/折叠、选择节点、节点操作等。可以通过添加额外的属性和子标签来实现这些功能。例如,使用`switchType="client"`可以让树的...

    richfaces中文开发文档

    3. **rich:extendedDataTable**:扩展的数据表格组件,支持分页、排序、过滤和Ajax更新。 4. **rich:popupPanel**:弹出面板组件,可以实现浮窗效果,常用于对话框和下拉菜单。 5. **rich:modalPanel**:模态窗口...

    richfaces参考文档

    - ****:用于数据表格的分页,提供多种滚动样式和行为。 - ****:一个动态的数据网格,可以展示大量数据,并支持排序、过滤和行操作。 - ****:创建可扩展的树形视图,支持拖放操作和节点状态管理。 - ****:增强...

    RichFaces中的ajax组件实现刷新验证码

    在探讨“RichFaces中的ajax组件实现刷新验证码”的技术细节时,我们首先需要理解RichFaces框架以及AJAX在其中的应用。RichFaces是一个基于JavaServer Faces(JSF)的开源UI组件库,它提供了丰富的用户界面组件,包括...

    richfaces4.0所需jar包

    3. **richfaces-core-impl-4.0.0.Final.jar**:这是RichFaces核心实现的库,包含了许多基础服务和功能,如事件处理、Ajax支持、皮肤化和渲染。这个库是RichFaces框架的核心部分,负责处理与JSF集成、请求处理和组件...

    JSF分页控件 ,支持大容量可查询分页

    在JSF中,分页通常通过自定义组件或利用现有的第三方库如PrimeFaces、RichFaces等实现。 "JSF分页控件" 可能是基于某个特定的JSF库,比如PrimeFaces中的`p:datascroller`或`p:paginator`,或者自定义的组件。这些...

    richfaces实现ajax带进度条的上传

    "RichFaces"是一个功能强大的JavaServer Faces (JSF)组件库,它提供了丰富的用户界面元素和Ajax功能,使得开发人员能够构建出更加动态和交互性强的网页应用。本教程将详细讲解如何利用RichFaces实现带有进度条的AJAX...

Global site tag (gtag.js) - Google Analytics