rich:tree Drag&Drop not working
frisch Feb 11, 2010 9:43 AMHi all,
I have tried to get the rich:tree Drag&Drop example running but no luck. I have simply copied the xhtml and java code that were available on the site, the pictures and my page is displayed correctly. I get the picture preview on the right side of the page but there is simply no Drag or Drop support.
Can anybody tell me what I'm doing wrong? Did I miss anything?
Here is my code:
richTreeDragDrop.xhtml:
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich">
<style>
.col1, .col2 {
width:50%;
vertical-align:top;
}
.rich-table-cell, .rich-table{
border:none;
}
.indicatorPicture {
width: 80px;
}
</style>
<rich:dragIndicator id="indicator1" >
<f:facet name="single">
<h:graphicImage styleClass="indicatorPicture" value="/richfaces/{draggedImage}" />
</f:facet>
</rich:dragIndicator>
<rich:dragIndicator id="indicator2" />
<h:form>
<h:panelGrid columns="2" width="100%" columnClasses="col1,col2">
<rich:tree style="width:300px" nodeSelectListener="#{simpleTreeDndBean.processSelection}"
reRender="selectedNode" ajaxSubmitSelection="true" switchType="client" dragIndicator="indicator2"
value="#{simpleTreeDndBean.treeNode}" var="item" id="tree" treeNodeVar="treeNode"
dropListener="#{simpleTreeDndBean.dropListener}" nodeFace="#{treeNode.parent.parent == null ? 'node' : 'leaf'}">
<rich:treeNode type="node" acceptedTypes="pic" icon="#{treeNode.icon}" iconLeaf="#{treeNode.leafIcon}">
<h:outputText value="#{item}"/>
</rich:treeNode>
<rich:treeNode type="leaf" dragType="pic">
<rich:dndParam name="label" type="drag">#{item}</rich:dndParam>
<h:outputText value="#{item}"/>
</rich:treeNode>
</rich:tree>
<rich:panel id="selectedNode">
<rich:dataGrid id="selectedNodeGrid" style="display: #{!empty simpleTreeDndBean.selectedNodeChildren ? '' : 'none'}" value="#{simpleTreeDndBean.selectedNodeChildren}" var="item" columns="3" border="0">
<rich:dragSupport dragIndicator="indicator1" dragType="pic" dragValue="#{item}" reRender="selectedNodeGrid">
<rich:dndParam name="draggedImage" value="#{item.data}"/>
</rich:dragSupport>
<h:graphicImage value="/richfaces/#{item.data}" />
</rich:dataGrid>
</rich:panel>
</h:panelGrid>
</h:form>
</ui:composition>
SimpleTreeDndBean.java
/**
* License Agreement.
*
* JBoss RichFaces - Ajax4jsf Component Library
*
* Copyright (C) 2007 Exadel, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package de.lyth.admintool.handler;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import javax.annotation.PostConstruct;
import javax.faces.FacesException;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import org.ajax4jsf.context.AjaxContext;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.Synchronized;
import org.richfaces.component.UIDragSupport;
import org.richfaces.component.UITree;
import org.richfaces.component.UITreeNode;
import org.richfaces.component.html.HtmlTree;
import org.richfaces.event.DropEvent;
import org.richfaces.event.NodeSelectedEvent;
import org.richfaces.model.TreeNode;
import org.richfaces.model.TreeRowKey;
@Name("simpleTreeDndBean")
@Scope(ScopeType.PAGE)
public class SimpleTreeDndBean {
private TreeNode rootNode = null;
private List<TreeNode<String>> selectedNodeChildren = new ArrayList<TreeNode<String>>();
private String nodeTitle;
private static final String ICONS_PATH = "/richfaces/";
private static final String DATA_PATH = "/richfaces/simple-tree-data-dnd.properties";
@PostConstruct
public void init(){
System.out.println("init");
}
private void addNodes(String path, TreeNode node, Properties properties) {
boolean end = false;
int counter = 1;
while (!end) {
String key = path != null ? path + '.' + counter : String.valueOf(counter);
String value = properties.getProperty(key);
if (value != null) {
DemoTreeNodeImpl nodeImpl = new DemoTreeNodeImpl();
String[] splittedValue = value.split(" - ");
if (splittedValue.length > 1) {
nodeImpl.setData(splittedValue[0]);
nodeImpl.setType(splittedValue[1]);
if (splittedValue.length>2){
nodeImpl.setIcon(ICONS_PATH+splittedValue[2]);
nodeImpl.setLeafIcon(ICONS_PATH+splittedValue[2]);
}
if (splittedValue.length>3){
nodeImpl.setLeafIcon(ICONS_PATH+splittedValue[3]);
}
node.addChild(new Integer(counter), nodeImpl);
}
addNodes(key, nodeImpl, properties);
counter++;
} else {
end = true;
}
}
}
private void loadTree() {
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
InputStream dataStream = externalContext.getResourceAsStream(DATA_PATH);
try {
Properties properties = new Properties();
properties.load(dataStream);
rootNode = new DemoTreeNodeImpl();
addNodes(null, rootNode, properties);
} catch (IOException e) {
throw new FacesException(e.getMessage(), e);
} finally {
if (dataStream != null) {
try {
dataStream.close();
} catch (IOException e) {
externalContext.log(e.getMessage(), e);
}
}
}
}
public void processSelection(NodeSelectedEvent event) {
HtmlTree tree = (HtmlTree) event.getComponent();
nodeTitle = (String) tree.getRowData();
selectedNodeChildren.clear();
TreeNode<String> currentNode = tree.getModelTreeNode(tree.getRowKey());
DemoTreeNodeImpl<String> demoCurrentNodeImpl = currentNode instanceof DemoTreeNodeImpl ? (DemoTreeNodeImpl) currentNode : null;
if (currentNode.isLeaf() && (demoCurrentNodeImpl != null && demoCurrentNodeImpl.getType().toLowerCase().equals("leaf") || demoCurrentNodeImpl == null )) {
selectedNodeChildren.add(currentNode);
} else {
Iterator<Map.Entry<Object, TreeNode<String>>> it = currentNode.getChildren();
while (it != null && it.hasNext()) {
Map.Entry<Object, TreeNode<String>> entry = it.next();
selectedNodeChildren.add(entry.getValue());
}
}
}
private Object getNewId(TreeNode parentNode) {
Map<Object, TreeNode> childs = new HashMap<Object, TreeNode>();
Iterator<Map.Entry<Object, TreeNode>> iter = parentNode.getChildren();
while (iter != null && iter.hasNext()) {
Map.Entry<Object, TreeNode> entry = iter.next();
childs.put(entry.getKey(), entry.getValue());
}
Integer index = 1;
while (childs.containsKey(index)) {
index++;
}
return index;
}
public void dropListener(DropEvent dropEvent) {
// resolve drag destination attributes
UITreeNode destNode = (dropEvent.getSource() instanceof UITreeNode) ? (UITreeNode) dropEvent.getSource() : null;
UITree destTree = destNode != null ? destNode.getUITree() : null;
TreeRowKey dropNodeKey = (dropEvent.getDropValue() instanceof TreeRowKey) ? (TreeRowKey) dropEvent.getDropValue() : null;
TreeNode droppedInNode = dropNodeKey != null ? destTree.getTreeNode(dropNodeKey) : null;
// resolve drag source attributes
UITreeNode srcNode = (dropEvent.getDraggableSource() instanceof UITreeNode) ? (UITreeNode) dropEvent.getDraggableSource() : null;
UITree srcTree = srcNode != null ? srcNode.getUITree() : null;
TreeRowKey dragNodeKey = (dropEvent.getDragValue() instanceof TreeRowKey) ? (TreeRowKey) dropEvent.getDragValue() : null;
TreeNode draggedNode = dragNodeKey != null ? srcTree.getTreeNode(dragNodeKey) : null;
if (dropEvent.getDraggableSource() instanceof UIDragSupport && srcTree == null && draggedNode == null && dropEvent.getDragValue() instanceof TreeNode) {
srcTree = destTree;
draggedNode = (TreeNode) dropEvent.getDragValue();
dragNodeKey = srcTree.getTreeNodeRowKey(draggedNode) instanceof TreeRowKey ? (TreeRowKey) srcTree.getTreeNodeRowKey(draggedNode) : null;
}
// Note: check if we dropped node on to itself or to item instead of
// folder here
if (droppedInNode != null && (droppedInNode.equals(draggedNode) || droppedInNode.getParent().getParent() != null || draggedNode.getParent().getParent() == null)) {
return;
}
if (dropNodeKey != null) {
// add destination node for rerender
destTree.addRequestKey(dropNodeKey);
Object state = null;
if (dragNodeKey != null) { // Drag from this or other tree
TreeNode parentNode = draggedNode.getParent();
// 1. remove node from tree
state = srcTree.removeNode(dragNodeKey);
// 2. add parent for rerender
Object rowKey = srcTree.getTreeNodeRowKey(parentNode);
srcTree.addRequestKey(rowKey);
if (dropEvent.getDraggableSource() instanceof UIDragSupport) {
selectedNodeChildren.remove(draggedNode);
// if node was gragged in it's parent place dragged node to
// the end of selected nodes in grid
if (droppedInNode.equals(parentNode)) {
selectedNodeChildren.add(draggedNode);
}
}
} else if (dropEvent.getDragValue() != null) { // Drag from some
// drag source
draggedNode = new DemoTreeNodeImpl<String>();
draggedNode.setData(dropEvent.getDragValue().toString());
}
// generate new node id
Object id = getNewId(destTree.getTreeNode(dropNodeKey));
destTree.addNode(dropNodeKey, draggedNode, id, state);
}
AjaxContext ac = AjaxContext.getCurrentInstance();
// Add destination tree to reRender
try {
ac.addComponentToAjaxRender(destTree);
} catch (Exception e) {
System.err.print(e.getMessage());
}
}
public List<TreeNode<String>> getSelectedNodeChildren() {
return selectedNodeChildren;
}
public void setSelectedNodeChildren(List<TreeNode<String>> selectedNodeChildren) {
this.selectedNodeChildren = selectedNodeChildren;
}
public TreeNode getTreeNode() {
if (rootNode == null) {
loadTree();
}
return rootNode;
}
public String getNodeTitle() {
return nodeTitle;
}
public void setNodeTitle(String nodeTitle) {
this.nodeTitle = nodeTitle;
}
}
DemoTreeNodeImpl.java:
package de.lyth.admintool.handler;
import org.jboss.seam.annotations.Name;
import org.richfaces.model.TreeNodeImpl;
/* TODO Class description goes here.
* @author Alexandr Levkovsky
*
*/
@Name("demoTreeNodeImpl")
public class DemoTreeNodeImpl<T> extends TreeNodeImpl<T> {
private static final long serialVersionUID = 1L;
private String icon;
private String leafIcon;
private String type;
/**
* @return the type
*/
public String getType() {
return type;
}
/**
* @param type the type to set
*/
public void setType(String type) {
this.type = type;
}
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;
}
}
I'm currently working with the 3.3.2.SR1 version of the richfaces library.
I#ve also attached a picture of my problem.
Thanks
-
RichTreeDragDrop.png 158.8 KB