7 Replies Latest reply on Aug 29, 2013 6:27 AM by dlee606

    Lazy load treenode

    burton999

      Hi.

      I am using richfaces 4.2.0.Final.

      I have tried to implement file explorer.

      I want to load child files when user clicks tree node of folder.

      Is it possible?

      I read the document, but I was not able to find the way.

        • 1. Re: Lazy load treenode
          iabughosh

          yes you can do this by using toggleListener on rich:treeNode :

          <rich:treeNode title="#{node.label}"

                                type="myType"                                          

                                toggleListener="#{myBean.treeToggleListener}">

                                <h:outputText value="#{node.label}" />

          </rich:treeNode>

           

          public void myTreeToggleListener(TreeToggleEvent tge) {    

              

          UITreeNode node = (UITreeNode)tge.getSource();

          UITreeModelRecursiveAdaptor treeModel = (UITreeModelRecursiveAdaptor)node.getParent();

          List<MainTreeNode> nodes = (List<MainTreeNode>)treeModel.getNodes();

           

          //here you can use nodes to add more new nodes

          }

           

           

          where MainTreeNode is a class extends TreeNodeImpl class.

           

          good luck.

          • 2. Re: Lazy load treenode
            burton999

            Thank you for quick reply.

            I tried to write code like the following.

             

            <rich:tree

                value="#{fileSystemBean.rootDrives}"

                var="node"

                nodeType="#{node.type}"

                toggleType="ajax"

                selectionType="ajax"

                selectionChangeListener="#{fileSystemBean.processTreeSelectionChange}">

               

                <rich:treeNode toggleListener="#{fileSystemBean.processTreeToggle}" type="drive">

                    #{node.name}

                </rich:treeNode>

                <rich:treeNode toggleListener="#{fileSystemBean.processTreeToggle}" type="directory">

                    #{node.name}

                </rich:treeNode>

            </rich:tree>

             

             

            @ManagedBean(name = "fileSystemBean")

            @RequestScoped

            public class FileSystemBean implements Serializable {

               

                private static final long serialVersionUID = 8487126082219699755L;

                private List<FileSystemNode> driveNodes;

                private FileSystemNode currentSelection;

               

                public synchronized List<FileSystemNode> getRootDrives() {

                    if (this.driveNodes == null) {

                        driveNodes = new ArrayList<FileSystemNode>();

                        for (File file : File.listRoots()) {

                            driveNodes.add(new FileSystemNode(file, true));

                        }

                    }

                    return driveNodes;

                }

               

                public void processTreeToggle(TreeToggleEvent event) {

                    UITreeNode node = (UITreeNode)event.getSource();

                    UITree tree = (UITree)node.getParent();

                    FileSystemNode selectedNode = (FileSystemNode)tree.getRowData();

                    Iterator<Object> keys = selectedNode.getChildrenKeysIterator();

                    for (FileSystemNode child : selectedNode.getDirectories()) {

                        selectedNode.addChild(child.getFile().hashCode(), child);

                    }

                }

                public static class FileSystemNode extends org.richfaces.model.TreeNodeImpl {

                   

                    private final File file;

                    private final boolean isDrive;

                    private List<FileSystemNode> directories;

                   

                    public FileSystemNode(File file, boolean isDrive) {

                        this.file = file;

                        this.isDrive = isDrive;

                    }

                    public String getType() {

                        if (this.isDrive) {

                            return "drive";

                        } else {

                            return "directory";

                        }

                    }

                    public String getName() {

                        if (this.isDrive) {

                            return this.file.getAbsolutePath();

                        } else {

                            return this.file.getName();

                        }

                    }

                    public File getFile() {

                        return this.file;

                    }

                    public synchronized List<FileSystemNode> getDirectories() {

                        if (this.directories == null) {

                            this.directories = new ArrayList<FileSystemNode>();

                            for (File child : this.file.listFiles(new DirectoryFilter())) {

                                this.directories.add(new FileSystemNode(child, false));

                            }

                        }

                        return this.directories;

                    }

                }

                public FileSystemNode getCurrentSelection() {

                    return currentSelection;

                }

                /**

                 *

                 */

                public static class DirectoryFilter implements FileFilter {

                    @Override

                    public boolean accept(File file) {

                        return file.isDirectory();

                    }

                }

            }

             

             

            However, the following exception occurs when application run.

             

            FileSystemBean$FileSystemNode cannot be cast to javax.swing.tree.TreeNode.

             

            This exception dose not occur if I use treeModelRecursiveAdaptor.

            Using treeModelRecursiveAdaptor is required?

             

            Sorry for my poor English :-(

            • 3. Re: Lazy load treenode
              iabughosh

              hello burton,

              for your cuurent xhtml you need to do this:

              1-make your FileSystemNode class extends TreeNode.

              2-there is no need to make your FileSystemNode class static.

               

               

              if you later decided to use treeAdapters then you can make your FileSystemNode class extends TreeNodeImpl.

               

              regards.

              1 of 1 people found this helpful
              • 4. Re: Lazy load treenode
                burton999

                Thanks a lot.

                I was able to lazy load by using treeModelRecursiveAdaptor.

                following is my code.

                 

                <rich:tree

                    var="node"

                    toggleType="ajax"

                    selectionType="ajax"

                    selectionChangeListener="#{fileSystemBean.processTreeSelectionChange}"

                    nodeType="#{node.type}">

                   

                    <rich:treeModelRecursiveAdaptor roots="#{fileSystemBean.rootDrives}" nodes="#{node.directories}" leaf="#{node.leaf}">

                        <rich:treeNode type="drive" iconCollapsed="../images/drive.png" iconExpanded="../images/drive.png" iconLeaf="../images/drive.png">

                            <h:outputText value="#{node.name}"/>

                        </rich:treeNode>

                        <rich:treeNode type="directory" iconCollapsed="../images/folder.png" iconExpanded="../images/folder.png" iconLeaf="../images/folder.png">

                            <h:outputText value="#{node.name}"/>

                        </rich:treeNode>

                    </rich:treeModelRecursiveAdaptor>

                </rich:tree>

                 

                @ManagedBean(name = "fileSystemBean")

                @RequestScoped

                public class FileSystemBean implements Serializable {

                   

                    private static final Logger LOGGER = LoggerFactory.getLogger(FileSystemBean.class);

                    private static final long serialVersionUID = 8487126082219699755L;

                    private List<FileSystemNode> driveNodes;

                    private FileSystemNode selectedNode;

                   

                    public synchronized List<FileSystemNode> getRootDrives() {

                        if (this.driveNodes == null) {

                            driveNodes = new ArrayList<FileSystemNode>();

                            for (File file : File.listRoots()) {

                                driveNodes.add(new FileSystemNode(file, true));

                            }

                        }

                        return driveNodes;

                    }

                   

                    public void processTreeSelectionChange(TreeSelectionChangeEvent event) {

                        List<Object> selection = new ArrayList<Object>(event.getNewSelection());

                        Object currentSelectionKey = selection.get(0);

                        UITree tree = (UITree) event.getSource();

                        tree.setRowKey(currentSelectionKey);

                        this.selectedNode = (FileSystemNode)tree.getRowData();

                        LOGGER.debug("SelectedNode=" + this.selectedNode.getFile());

                    }

                   

                    public static class FileSystemNode extends TreeNodeImpl {

                       

                        private final File file;

                        private final boolean isDrive;

                        private List<FileSystemNode> directories;

                       

                        public FileSystemNode(File file, boolean isDrive) {

                            this.file = file;

                            this.isDrive = isDrive;

                        }

                        public String getType() {

                            if (this.isDrive) {

                                return "drive";

                            } else {

                                return "directory";

                            }

                        }

                        public String getName() {

                            if (this.isDrive) {

                                return this.file.getAbsolutePath();

                            } else {

                                return this.file.getName();

                            }

                        }

                        public File getFile() {

                            return this.file;

                        }

                        public synchronized List<FileSystemNode> getDirectories() {

                            if (this.directories == null) {

                                this.directories = new ArrayList<FileSystemNode>();

                                for (File child : this.file.listFiles(new DirectoryFilter())) {

                                    this.directories.add(new FileSystemNode(child, false));

                                }

                            }

                            return this.directories;

                        }

                        @Override

                        public boolean isLeaf() {

                            File[] children = this.file.listFiles(new DirectoryFilter());

                            if (children == null || children.length == 0) {

                                return true;

                            }

                            return false;

                        }

                    }

                    public FileSystemNode getSelectedNode() {

                        return this.selectedNode;

                    }

                    /**

                     *

                     */

                    public static class DirectoryFilter implements FileFilter {

                        @Override

                        public boolean accept(File file) {

                            return file.isDirectory();

                        }

                    }

                }

                • 5. Re: Lazy load treenode
                  atarifreak73

                  Thank You!!!! This i have several hours looking for!!

                  • 6. Re: Lazy load treenode
                    agallo73

                    Hello, I am actually unable to see lazy loading on a tree with a custom adaptor in my application.

                     

                    I also tried to use burton's example above to figure out whether i  was making some mistakes  but also using this sample, I can  just see the root nodes without any possibility to expnd them even if the isLeaf method is correctly invoked on the FileSystemNode elements.

                     

                    This is what I actually see.

                     

                    I suppose that using the recursive adaptor with toggleclient="ajax" lazy loading should show up when expanding nodes.

                     

                    But How can it be accomplished if there's no way to expand the tree?

                     

                    I also added the tree within a form but with the same result.

                     

                    I'm using richfaces 4.3.020120802-M1

                     

                    Can someone help me please?

                     

                    Thanks in advance.

                     

                    Antonio.

                     

                     

                    • 7. Re: Lazy load treenode
                      dlee606

                      Hi Burton,

                       

                      I try to use same stuff with your code,

                      but I got some problem -- the "processTreeSelectionChange(TreeSelectionChangeEvent event) {" never get called.

                      Any idea?