tree + drag & drop : dropped node is not added to the tree w
fr.evrard Mar 18, 2009 5:11 AMhi,
I try to implement the sample of the drag & drop on a tree presented in the richfaces documentation page from : http://www.jboss.org/file-access/default/members/jbossrichfaces/freezone/docs/devguide/en/html/tree.html
This sample doc refers to one method called "processDrop", I have tried with this implementation but this doesn't works very well, because the dragged object is well remove from the parent treeNode source but is not added to the dropNode (but in the model of the tree, it seems that the dropped object have been added, is there an bug in the refresh process of the tree after the drop event ? I don't knwo why).
Could anyone send me any working sample for this processDrop method ?
Here's my implementation from a compilation from RichFaces 3.3.0 sample code :
import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.StringTokenizer; import javax.faces.context.FacesContext; import javax.swing.text.html.HTMLDocument.HTMLReader.IsindexAction; import org.ajax4jsf.context.AjaxContext; 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; public class Library implements TreeNode { /** * */ private static final long serialVersionUID = -3530085227471752526L; private Map artists = null; private Object state1; private Object state2; private List<Song> songsList; private Set<Song> selectedSongsSet = new HashSet<Song>(); private List<Song> selectedSongsList = new ArrayList<Song>(); public Library() { songsList = new ArrayList<Song>(); songsList.addAll(getLibraryAsList()); } private Map getArtists() { if (this.artists == null) { initData(); } return this.artists; } public void addArtist(Artist artist) { addChild(Long.toString(artist.getId()), artist); } public void addChild(Object identifier, TreeNode child) { getArtists().put(identifier, child); child.setParent(this); } public TreeNode getChild(Object id) { return (TreeNode) getArtists().get(id); } public Iterator getChildren() { return getArtists().entrySet().iterator(); } public Object getData() { return this; } public TreeNode getParent() { return null; } public boolean isLeaf() { return getArtists().isEmpty(); } public void removeChild(Object id) { getArtists().remove(id); } public void setData(Object data) { } public void setParent(TreeNode parent) { } public String getType() { return "library"; } private long nextId = 0; private long getNextId() { return nextId++; } private Map albumCache = new HashMap(); private Map artistCache = new HashMap(); private Artist getArtistByName(String name, Library library) { Artist artist = (Artist) artistCache.get(name); if (artist == null) { artist = new Artist(getNextId()); artist.setName(name); artistCache.put(name, artist); library.addArtist(artist); } return artist; } private Album getAlbumByTitle(String title, Artist artist) { Album album = (Album) albumCache.get(title); if (album == null) { album = new Album(getNextId()); album.setTitle(title); albumCache.put(title, album); artist.addAlbum(album); } return album; } private void initData() { artists = new HashMap(); InputStream is = this.getClass().getClassLoader().getResourceAsStream("data/data.txt"); ByteArrayOutputStream os = new ByteArrayOutputStream(); byte[] rb = new byte[1024]; int read; try { do { read = is.read(rb); if (read > 0) { os.write(rb, 0, read); } } while (read > 0); String buf = os.toString(); StringTokenizer toc1 = new StringTokenizer(buf, "\n"); while (toc1.hasMoreTokens()) { String str = toc1.nextToken(); StringTokenizer toc2 = new StringTokenizer(str, "\t"); String songTitle = toc2.nextToken(); String artistName = toc2.nextToken(); String albumTitle = toc2.nextToken(); toc2.nextToken(); toc2.nextToken(); String albumYear = toc2.nextToken(); Artist artist = getArtistByName(artistName, this); Album album = getAlbumByTitle(albumTitle, artist); album.setYear(new Integer(albumYear)); Song song = new Song(getNextId()); song.setTitle(songTitle); album.addSong(song); } } catch (IOException e) { throw new RuntimeException(e); } } public Object getState1() { return state1; } public void setState1(Object state1) { this.state1 = state1; } public Object getState2() { return state2; } public void setState2(Object state2) { this.state2 = state2; } public void walk(TreeNode node, List<TreeNode> appendTo, Class<? extends TreeNode> type) { if (type.isInstance(node)) { appendTo.add(node); } Iterator<Map.Entry<Object, TreeNode>> iterator = node.getChildren(); while (iterator.hasNext()) { walk(iterator.next().getValue(), appendTo, type); } } public ArrayList getLibraryAsList() { ArrayList appendTo = new ArrayList(); walk(this, appendTo, Song.class); return appendTo; } public List<Song> getSongsList() { return songsList; } public void setSongsList(List<Song> songsList) { this.songsList = songsList; } public void takeSelection() { selectedSongsList.clear(); selectedSongsList.addAll(selectedSongsSet); } public Set<Song> getSelectedSongsSet() { return selectedSongsSet; } public void setSelectedSongsSet(Set<Song> selectedSongsSet) { this.selectedSongsSet = selectedSongsSet; } public List<Song> getSelectedSongsList() { return selectedSongsList; } public void setSelectedSongsList(List<Song> selectedSongsList) { this.selectedSongsList = selectedSongsList; } // ++ FED 160309 private List<String> complementInfo = new ArrayList<String>(); /** * on souhaite en plus de l'arbre, afficher une description complémentaire de l'item selectionné dans une zone de texte à droite de l'arborescence * * @param event * @return void */ public void processSelection(NodeSelectedEvent event) { HtmlTree tree = (HtmlTree) event.getComponent(); Object rowData = tree.getRowData(); complementInfo.clear(); // obtient le type de l'objet qui est selectionné, est-ce celui-ci ? if (rowData instanceof Song) { long id = ((Song) rowData).getId(); String title = ((Song) rowData).getTitle(); String parentID = ((Song) rowData).getParent().toString(); complementInfo.add("song id : " + id); complementInfo.add("title : " + title); complementInfo.add("parentID : " + parentID); } else if (rowData instanceof Album) { Album alb = (Album) rowData; complementInfo.add("id : " + alb.getId()); complementInfo.add("data : " + alb.getData()); complementInfo.add("title : " + alb.getTitle()); complementInfo.add("artist : " + alb.getArtist()); complementInfo.add("parentID : " + alb.getParent().toString()); complementInfo.add("childs : " + alb.getChildren().toString()); } } /** * @return the complementInfo */ public List<String> getComplementInfo() { return this.complementInfo; } /** * @param complementInfo * the complementInfo to set */ public void setComplementInfo(List<String> complementInfo) { this.complementInfo = complementInfo; } /** * gère le dépot d'un node dans sur un autre * * @param dropEvent * @return void */ 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; } FacesContext context = FacesContext.getCurrentInstance(); 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); // ++ FED 170309 1811 parentNode.removeChild(dragNodeKey); // 2. add parent for rerender Object rowKey = srcTree.getTreeNodeRowKey(parentNode); srcTree.addRequestKey(rowKey); // gère l'affichage de la zone d'affichage compélemtaire située à droite de l'arbre if (dropEvent.getDraggableSource() instanceof UIDragSupport) { // -- FED 160309 1233 selectedNodeChildren.remove(draggedNode); // if node was gragged in it's parent place dragged node to // the end of selected nodes in grid // -- FED 160309 1233 if (droppedInNode.equals(parentNode)) { // -- FED 160309 1233 selectedNodeChildren.add(draggedNode); // -- FED 160309 1233 } } } else if (dropEvent.getDragValue() != null) { System.out.print(dropEvent.getDragValue().toString()); // Drag from some drag source (mais pas un noeud existant (autre objet mais contenant des données)) // -- FED 160309 1233 draggedNode = new DemoTreeNodeImpl<String>(); // -- FED 160309 1233 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()); } // Add source tree to reRender try { ac.addComponentToAjaxRender(srcTree); } catch (Exception e) { System.err.print(e.getMessage()); } } /** * @param parentNode * @return * @return Object */ 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; } }
tks a lot,
Franck.