richfaces3.3.1中树的节点的拖动

前段时间,因为公司分配了这样的任务,开始研究了richfaces3.3.1的demo。其中关于树的拖动部分,通过研究demo的例子,我做了一些修改,实现了下面的功能:

1.树的动态加载;

2.一棵树内的节点的拖动,只能从叶子节点拖动到非叶子节点。

 

不过,我想实现更复杂的拖动树在这基础上修改也不会太难。

 

下面贴代码吧:

/pages/tree/下的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>tree demo</title>
        
    </head>
    <style>
        .col1, .col2 {
        width:50%;
        vertical-align:top;
        }
        .rich-table-cell, .rich-table{
        border:none;
        }
    </style>
    <body>
        <f:view>
            <div id="top">
                <h3>tree demo about drag and drop</h3>
            </div>
            <rich:dragIndicator id="indicator1" />
            <h:form>	
                <h:panelGrid columns="1" width="100%" columnClasses="col1">
                    
                    <rich:tree style="width:300px"
                               switchType="ajax" value="#{treesBean.treeNode}" var="item" id="tree" 
                               treeNodeVar="treeNode"
                               nodeFace="#{item.type == 1 ? 'node' : 'leaf'}">
                        <rich:treeNode type="node" acceptedTypes="all"  dropListener="#{evntBean.processDrop}" 
                                       dropValue="#{treeNode}" icon="#{treeNode.icon}" iconLeaf="#{treeNode.leafIcon}"
                                       changeExpandListener="#{treesBean.processExpansion}" data="#{treeNode}" reRender="tree"> 
                            <h:outputText value="#{item.nodeName}"/>
                        </rich:treeNode>
                        <rich:treeNode type="leaf" dragType="all" dragValue="#{treeNode}" icon="#{treeNode.icon}" iconLeaf="#{treeNode.leafIcon}"  dragIndicator="indicator1" dragListener="#{evntBean.processDrag}">
                            <rich:dndParam name="label" type="drag" value="#{item.nodeName}"></rich:dndParam>
                            
                            <h:outputText value="#{item.nodeName}"/>
                        </rich:treeNode>
                    </rich:tree>
                </h:panelGrid>
                
            </h:form>
        </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"/>
                <mapping resource="/demo/tree/NodeVo.hbm.xml"/>
	</session-factory>
</hibernate-configuration>

package demo.tree下的class和*.hbm.xml:

package demo.tree;

import org.richfaces.model.TreeNodeImpl;

public class DemoTreeNodeImpl extends TreeNodeImpl{
    
    private String icon;//节点icon
    private String leafIcon;//叶子节点icon
    private int nodeId;//节点id
    
    private int type;//节点类型:1-节点  2-叶子节点
    
    private int status;//节点的状态: 1-展开状态  0-折叠状态
    
    
    public String getIcon() {
        return icon;
    }
    
    public void setIcon(String icon) {
        this.icon = icon;
    }
    
    public String getLeafIcon() {
        return leafIcon;
    }
    
    public void setLeafIcon(String leafIcon) {
        this.leafIcon = leafIcon;
    }
    
    
    public int getNodeId() {
        return nodeId;
    }
    
    public void setNodeId(int nodeId) {
        this.nodeId = nodeId;
    }

    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }

    public int getStatus() {
        return status;
    }

    public void setStatus(int status) {
        this.status = status;
    }


    
}

 

package demo.tree;


import org.richfaces.component.Dropzone;
import org.richfaces.component.Draggable;
import org.richfaces.event.DropEvent;
import org.richfaces.event.DragEvent;
import org.richfaces.event.DropListener;
import org.richfaces.event.DragListener;
import org.richfaces.component.UITree;
import org.richfaces.component.UITreeNode;

import org.ajax4jsf.context.AjaxContext;


public class EventBean implements DropListener,DragListener{//,NodeExpandedListener{
    private TreesBean treesBean;
    private Object dragValue;
    
    /**
     * 处理树内子节点拖动(到节点)操作
     */
    public void processDrop(DropEvent dropEvent) {
        Dropzone dropzone = (Dropzone) dropEvent.getComponent();
        treesBean.move(dragValue, dropzone.getDropValue());
        
        UITree destTree = null;
        if(dropEvent.getSource() instanceof UITreeNode){
            UITreeNode destNode = (UITreeNode)dropEvent.getSource();
            destTree = destNode.getUITree();
        }else if(dropEvent.getSource() instanceof UITree){
            destTree = (UITree)dropEvent.getSource();
        }

        AjaxContext ac = AjaxContext.getCurrentInstance();
        // Add destination tree to reRender
        try {
            ac.addComponentToAjaxRender(destTree);
        } catch (Exception e) {
            System.err.print("ac.addComponentToAjaxRender(destTree):" + e.getMessage());
        }
    }
    
    public void processDrag(DragEvent dragEvent){
        Draggable draggable = (Draggable)dragEvent.getComponent();
        dragValue = draggable.getDragValue();
    }
    
    
    public TreesBean getTreesBean() {
        return treesBean;
    }
    
    public void setTreesBean(TreesBean treesBean) {
        this.treesBean = treesBean;
    }
    
    
}

 

/*
 * NodeVo.java
 * pojo类 hibernate entitybean
 */

package demo.tree;

public class NodeVo{
    private int id;
    private int nodeId;//节点id
    private String nodeName;//节点名
    private int parentNodeId;//父节点id
    private int type;//节点类型:1-节点 0-子节点
    private String icon;//节点icon
    private String leafIcon;//子节点icon

    /**
     * Creates a new instance of NodeVo
     */
    public NodeVo() {
    }

    /**
     * @return the id
     */
    public int getId() {
        return id;
    }

    /**
     * @param id the id to set
     */
    public void setId(int id) {
        this.id = id;
    }

    /**
     * @return the nodeId
     */
    public int getNodeId() {
        return nodeId;
    }

    /**
     * @param nodeId the nodeId to set
     */
    public void setNodeId(int nodeId) {
        this.nodeId = nodeId;
    }

    /**
     * @return the nodeName
     */
    public String getNodeName() {
        return nodeName;
    }

    /**
     * @param nodeName the nodeName to set
     */
    public void setNodeName(String nodeName) {
        this.nodeName = nodeName;
    }

    /**
     * @return the parentNodeId
     */
    public int getParentNodeId() {
        return parentNodeId;
    }

    /**
     * @param parentNodeId the parentNodeId to set
     */
    public void setParentNodeId(int parentNodeId) {
        this.parentNodeId = parentNodeId;
    }

    /**
     * @return the type
     */
    public int getType() {
        return type;
    }

    /**
     * @param type the type to set
     */
    public void setType(int type) {
        this.type = type;
    }

    /**
     * @return the icon
     */
    public String getIcon() {
        return icon;
    }

    /**
     * @param icon the icon to set
     */
    public void setIcon(String icon) {
        this.icon = icon;
    }

    /**
     * @return the leafIcon
     */
    public String getLeafIcon() {
        return leafIcon;
    }

    /**
     * @param leafIcon the leafIcon to set
     */
    public void setLeafIcon(String leafIcon) {
        this.leafIcon = leafIcon;
    }

}

 

package demo.tree;

import java.util.List;

import org.richfaces.model.TreeNode;
import org.richfaces.event.NodeExpandedEvent;
import org.richfaces.component.html.HtmlTreeNode;
import javax.faces.context.FacesContext;

import org.hibernate.Session;

import demo.util.DBUtil;

public class TreesBean {
    
    private DemoTreeNodeImpl rootNode = null;
    
    private static final String ICONS_PATH = "/images/tree/dnd/";
    
    public TreesBean(){
        loadTree(1000);//load tree which root node Id is 1000
    }
    
    /**
     * 为节点node加载第一层子节点
     */
    private void addNodes(DemoTreeNodeImpl node) {
        
        String sql = "from NodeVo where parentNodeId=:nodeId";
        Session ss = DBUtil.getSf().openSession();
        List list = ss.createQuery(sql).setInteger("nodeId", node.getNodeId()).list();
        ss.close();
        
        node.removeChild("fakeNode");
        
        if(null != list && list.size() > 0){
            for(int i=0;i<list.size();i++){
                NodeVo o = (NodeVo)list.get(i);
                DemoTreeNodeImpl tmpNode = new DemoTreeNodeImpl();
                tmpNode.setNodeId(o.getNodeId());
                tmpNode.setType(o.getType());
                tmpNode.setData(o);
                if(o.getType() == 1){//node
                    if("Unsorted".equalsIgnoreCase(o.getNodeName())){
                        tmpNode.setIcon(ICONS_PATH + "image.gif");
                        tmpNode.setLeafIcon(ICONS_PATH + "image.gif");
                    }else if("Favorites".equalsIgnoreCase(o.getNodeName())){
                        tmpNode.setIcon(ICONS_PATH + "favorites.gif");
                        tmpNode.setLeafIcon(ICONS_PATH + "favorites.gif");
                    }else if("Trash".equalsIgnoreCase(o.getNodeName())){
                        tmpNode.setIcon(ICONS_PATH + "trash.gif");
                        tmpNode.setLeafIcon(ICONS_PATH + "trash.gif");
                    }else{
                        tmpNode.setIcon(ICONS_PATH + "iconFolder.gif");
                        tmpNode.setLeafIcon(ICONS_PATH + "iconFolder.gif");
                    }
                }else if(o.getType() == 0){//leaf
                    tmpNode.setLeafIcon(ICONS_PATH + "disc.gif");
                }
                
                
                tmpNode.setParent(node);
                node.addChild(new Integer(tmpNode.getNodeId()), tmpNode);
                
                if(tmpNode.getType() == 1){
                    //构造一个假的的子结点
                    DemoTreeNodeImpl fakeNode = new DemoTreeNodeImpl();
                    NodeVo vo = new NodeVo();
                    vo.setNodeName("loading...");
                    vo.setType(1);
                    fakeNode.setData(vo);
                    fakeNode.setIcon(ICONS_PATH + "loading.gif");
                    fakeNode.setLeafIcon(ICONS_PATH + "loading.gif");
                    fakeNode.setType(1);
                    tmpNode.addChild("fakeNode",fakeNode);
                }
                
            }
        }
        
    }
    
    /**
     * 加载节点id为nodeId的树
     */
    private void loadTree(int nodeId) {
        Session ss = DBUtil.getSf().openSession();
        String sql = "from NodeVo where parentNodeId = 0 and nodeId=:nodeId";
        Object o = ss.createQuery(sql).setInteger("nodeId", nodeId).uniqueResult();
        ss.close();
        
        if (null != o) {
            NodeVo nodeVo = (NodeVo) o;
            rootNode = new DemoTreeNodeImpl();
            rootNode.setNodeId(nodeVo.getNodeId());
            rootNode.setData(nodeVo);
            rootNode.setParent(null);
            
            addNodes(rootNode);
        }
        
    }
    
    
    /**
     * 拖动树的叶子节点到节点
     */
    public void move(Object dragObj,Object dropObj){
        DemoTreeNodeImpl dragNode = (DemoTreeNodeImpl)dragObj;
        DemoTreeNodeImpl dropNode = (DemoTreeNodeImpl)dropObj;
        
        TreeNode dragParentNode = dragNode.getParent();
        if(null != dragParentNode){
            if(((DemoTreeNodeImpl)dragParentNode).getNodeId() == dropNode.getNodeId()){
                //在父结点内拖动无操作
                return;
            }
        }
        
        String sql = "from NodeVo where nodeId=:nodeId";
        Session ss = DBUtil.getSf().openSession();
        Object o = ss.createQuery(sql).setInteger("nodeId",dragNode.getNodeId()).uniqueResult();
        
        if(null != o){
            NodeVo nodeVo = (NodeVo)o;
            nodeVo.setParentNodeId(dropNode.getNodeId());
            ss.beginTransaction().begin();
            ss.update(nodeVo);
            ss.beginTransaction().commit();
            ss.flush();
        }
        ss.close();
        
        NodeVo vo = (NodeVo)dragNode.getData();
        vo.setParentNodeId(dropNode.getNodeId());
        dragNode.setData(vo);
        dragParentNode.removeChild(new Integer(dragNode.getNodeId()));//这里必须先做删除操作,之后再做setParent()和addChild()操作,这与richfaces的具体实现有关
        dragNode.setParent(dropNode);
        dropNode.addChild(new Integer(dragNode.getNodeId()),dragNode);
        
        FacesContext.getCurrentInstance().renderResponse();
        
    }
    
     /**
      * 处理展开与折叠操作
      */
    public void processExpansion(NodeExpandedEvent e){
        HtmlTreeNode tNode = (HtmlTreeNode)e.getComponent();
        
        DemoTreeNodeImpl o = (DemoTreeNodeImpl)tNode.getData();
        if(o.getStatus() == 0){//当该结点处于折叠状态下,则加载该结点的第一次子结点
            addNodes(o);
            o.setStatus(1);
        }
    }
    
    
    public DemoTreeNodeImpl getTreeNode() {
        
        return rootNode;
    }
    
    public void setTreeNode(DemoTreeNodeImpl rootNode){
        this.rootNode = rootNode;
    }
}

 

<?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.tree">
  <class name="NodeVo" table="tree">
    <id column="id" name="id">
      <generator class="native"/>
    </id>
    <property name="nodeId" not-null="true"/>
    <property name="nodeName" not-null="true" type="java.lang.String"/>
    <property name="parentNodeId" not-null="true"/>
    <property name="type" not-null="true"/>
  </class>
</hibernate-mapping>

 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;
    }
    
}

 /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 tree demo-->
    <managed-bean>
        <managed-bean-name>treesBean</managed-bean-name>
        <managed-bean-class>demo.tree.TreesBean</managed-bean-class>
        <managed-bean-scope>session</managed-bean-scope>
    </managed-bean>
    <managed-bean>
        <managed-bean-name>evntBean</managed-bean-name>
        <managed-bean-class>demo.tree.EventBean</managed-bean-class>
        <managed-bean-scope>request</managed-bean-scope>
        <managed-property>
            <property-name>treesBean</property-name>
            <property-class>demo.tree.TreesBean</property-class>
            <value>#{treesBean}</value>
        </managed-property>
    </managed-bean>
    <!--(up) add by SailingLee about tree 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>

 

用到的类库见图片附件lib.jpg   :)

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