My JSF Books/Videos My JSF Tutorials OmniFaces/JSF PPTs
JSF 2.3 Tutorial
JSF Caching Tutorial
JSF Navigation Tutorial
JSF Scopes Tutorial
JSF Page Author Beginner's Guide
OmniFaces 2.3 Tutorial Examples
OmniFaces 2.2 Tutorial Examples
JSF Events Tutorial
OmniFaces Callbacks Usages
JSF State Tutorial
JSF and Design Patterns
JSF 2.3 New Features (2.3-m04)
Introduction to OmniFaces
25+ Reasons to use OmniFaces in JSF
OmniFaces Validators
OmniFaces Converters
JSF Design Patterns
Mastering OmniFaces
Reusable and less-verbose JSF code

My JSF Resources ...

Java EE Guardian
Member of JCG Program
Member MVB DZone
Blog curated on ZEEF
OmniFaces is an utility library for JSF, including PrimeFaces, RichFaces, ICEfaces ...

[OmniFaces Utilities] - Find the right JSF OmniFaces 2 utilities methods/functions

Search on blog

Petition by Java EE Guardians

Twitter

sâmbătă, 21 martie 2015

Expose a path as an OmniFaces tree (<o:tree>)

In this post you can see a use case for OmniFaces <o:tree>. This is a versatile component that allows us to put almost anything in a tree structure (e.g. see the editable tree). Next, we want to obtain a tree with the following features:

·         render tree as a folder tree style
·         collapse/expand folders by clicking on folder's icons (AJAX based)
·         select files by click the file name (AJAX based)

First, we write a simple class to encapsulate information about each file/folder. This class is named ItemEntity and is listed below (in order to list folder first, you need to define a custom compareTo()):

package beans;

import java.io.Serializable;
import java.util.Objects;

public class ItemEntity implements Serializable, Comparable {

  private static final long serialVersionUID = 1L;

  private String path;      // the absolute path of the folder/file
  private String name;      // the file/folder name
  private String size;      // the file size in bytes
  private String type;      // the artifact type: folder or file
  private boolean visible;  // specific to files for indicating visibility
  private boolean expanded; // specific to folders for indicating collapse/expand

  public ItemEntity() {
  }

  // for a folder
  public ItemEntity(String path, String name, String type, boolean expanded, boolean visible) {
    this.path = path;
    this.expanded = expanded;
    this.visible = visible;
    this.name = name;
    this.type = type;
  }

  // for a file
  public ItemEntity(String path, String name, String type, String size, boolean visible) {
    this.path = path;
    this.visible = visible;
    this.name = name;
    this.type = type;
    this.size = size;
  }

  public boolean isVisible() {
    return visible;
  }

  public void setVisible(boolean visible) {
    this.visible = visible;
  }      

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public String getSize() {
    return size;
  }

  public void setSize(String size) {
    this.size = size;
  }

  public String getType() {
    return type;
  }

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

  public boolean isExpanded() {
   return expanded;
  }

  public void setExpanded(boolean expanded) {
    this.expanded = expanded;
  }   

  public String getPath() {
    return path;
  }

  public void setPath(String path) {
    this.path = path;
  }       
   
  @Override
  public int hashCode() {
    int hash = 7;
    hash = 29 * hash + Objects.hashCode(this.name);
    return hash;
  }

  @Override
  public int compareTo(Object o) {
    ItemEntity it = (ItemEntity) o;
    if (it.getType().equals("folder")) {
        return 1;
    } else {
        return -1;
    }
  }

  @Override
  public boolean equals(Object obj) {
    if (obj == null) {
        return false;
    }
    if (getClass() != obj.getClass()) {
        return false;
    }
    final ItemEntity other = (ItemEntity) obj;
   if (!Objects.equals(this.name, other.name)) {
       return false;
   }
   return true;
  }

  @Override
  public String toString() {
   return name + "(" + size + ")";
  }
}

Next, we can use a recursive approach to traverse each folder/file of the given path. Each file/folder will become an instance of ItemEntity and it will be added in a SortedTreeModel (one of the TreeModel implementations). In addition, we need a method responsible to show/hide a folder content when the user expand (default)/collapse a folder. So, next, we have a write a bean (TreeBean) that uses the ItemEntity for representing each artifact obtained via a recursive method (simple folder traversal in a recursive approach). Each ItemEntity is placed in the SortedTreeModel. Moreover the showHideItems() methods is responsabile to show/hide a folder content (node tree children):

package beans;

import java.io.File;
import java.io.Serializable;
import javax.annotation.PostConstruct;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import org.omnifaces.model.tree.SortedTreeModel;
import org.omnifaces.model.tree.TreeModel;
import org.omnifaces.util.Faces;

@Named
@ViewScoped
public class TreeBean implements Serializable {
   
  private static final long serialVersionUID = 1L;
   
  private TreeModel<ItemEntity> tree;
  private String selected = "none";
   
  @PostConstruct
  public void init() {
    tree = new SortedTreeModel<>();
    // current application folder
    //walk(Faces.getRealPath("."), tree);
    // some local folder
     walk("D:\\Omnifaces\\blog", tree);
  }
   
  public TreeModel<ItemEntity> getTree() {
   return tree;
  }
   
  public void showHideItems(TreeModel<ItemEntity> node) {
    ItemEntity folderData = node.getData();
    for (TreeModel<ItemEntity> children : node.getChildren()) {
         ItemEntity fileData = children.getData();
         fileData.setVisible(!folderData.isExpanded());
    }
    folderData.setExpanded(!folderData.isExpanded());            
  }
   
  public void selectedFile(String selected){
    this.selected = selected;
  }

  public String getSelected() {
    return selected;
  }
   
  private void walk(String path, TreeModel<ItemEntity> treem) {
      
    File root = new File(path);
    File[] list = root.listFiles();
       
        if (list == null) {
            return;
        }
       
        for (File f : list) {
             if (f.isDirectory()) {
                 System.out.println("Directory: " + f.getName());
                 walk(f.getAbsolutePath(),treem.addChild(new ItemEntity(f.getAbsolutePath(), f.getName(),"folder",true,true)));
             } else {
                 treem.addChild(new ItemEntity(f.getAbsolutePath(),f.getName(),"file"," (" + String.valueOf(f.length())+" bytes)", true));
                 System.out.println("File: " + f.getName());
             }
        }
    }
}

Finally, the JSF page uses <o:tree> to reveal the SortedTreeModel:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:o="http://omnifaces.org/ui"
      xmlns:f="http://xmlns.jcp.org/jsf/core">
  <h:head>
    <title></title>               
  </h:head>
  <h:body>    
    <h3>Selected file: <h:outputText id="selectedFile" value="#{treeBean.selected}"/></h3>
    <h:panelGroup id="pathTree">           
      <h:form id="form">
        <o:tree value="#{treeBean.tree}" var="t" varNode="node">
          <o:treeNode>
            <ul type="none">
              <o:treeNodeItem>
                <li>       
                  <h:panelGroup rendered="#{t.type eq 'file' and t.visible}">                                  
                    <h:graphicImage library="default" name="icons/file.png" title="#{t.path}" alt="#{t.path}"/>
                    <h:commandLink value="#{t.name}" action="#{treeBean.selectedFile(t.path)}">
                      <f:ajax execute="@form" render=":selectedFile"/>
                    </h:commandLink>                                       
                    #{t.size}
                  </h:panelGroup>
                  <h:panelGroup rendered="#{t.type eq 'folder' and t.visible}">
                    <h:commandButton image="resources/default/icons/#{t.expanded ? 'folder_open':'folder_close'}.png" 
                                     action="#{treeBean.showHideItems(node)}">
                      <f:ajax execute="@form" render="@form" />
                    </h:commandButton>                                       
                    #{t.name}                                                                
                    <o:treeInsertChildren />
                  </h:panelGroup>                                                                     
                </li>                           
              </o:treeNodeItem>
            </ul>
          </o:treeNode>                   
        </o:tree>
      </h:form>
    </h:panelGroup>           
  </h:body>
</html>

Niciun comentariu :

Trimiteți un comentariu

JSF BOOKS COLLECTION

Postări populare

OmniFaces/JSF Fans

Follow by Email

Visitors Starting 4 September 2015

Locations of Site Visitors