5 Replies Latest reply on Nov 18, 2009 5:19 AM by Ilya Shaikovsky

    rich:tree with dynamic menu

    praveen jain Novice

      hi
      i am trying to run a example of Rich Tree with ContextMenu
      but i am gettign the exception
      my code is

      <f:view>
       <h:form>
      
      
       <rich:tree style="width:300px"
       nodeSelectListener="#{simpleTreeBean.processSelection}"
       reRender="selectedNode" ajaxSubmitSelection="true"
       switchType="client" value="#{simpleTreeBean.treeNode}" var="item">
       <rich:treeNode>
       <h:outputText value="#{item}" />
       <a4j:support event="oncontextmenu"
       oncomplete="#{rich:component('cm')}.doShow(event, {})"
       actionListener="#{simpleTreeBean.treeListener}" reRender="cm">
       <f:setPropertyActionListener value="#{item}"
       target="#{simpleTreeBean.nodeSelected}" />
       </a4j:support>
       </rich:treeNode>
      
       </rich:tree>
       <rich:contextMenu submitMode="ajax" id="cm"
       binding="#{simpleTreeBean.contextMenu}" />
      
      
       </h:form>
      </f:view>
      

      the bean is
      public class SimpleTreeBean {
      
       private TreeNode rootNode = null;
       private List<String> selectedNodeChildren = new ArrayList<String>();
       private ArrayList<String> child = new ArrayList<String>();
       private String nodeTitle;
       private static final String DATA_PATH = "/richfaces/tree/examples/simple-tree-data.properties";
       private ArrayList<String> treenode = new ArrayList<String>();
       private ContextMenu contextMenu;
       private String nodeSelected;
      
       public SimpleTreeBean() {
       for (int i = 1; i <= 3; i++) {
       treenode.add((i) + "");
       for (int j = 1; j <= 5; j++) {
       child.add((i * j) + "");
       }
       }
       }
      
       private void addNodes(String path, TreeNode node, ArrayList properties) {
       boolean end = false;
       int counter = 1;
      
       for (int count = 0; count < treenode.size(); count++) {
       // String key = path != null ? path + '.' + counter :
       // String.valueOf(counter);
      
       String value = treenode.get(count);// properties.getProperty(key);
       if (value != null) {
       TreeNodeImpl nodeImpl = new TreeNodeImpl();
       nodeImpl.setData(value);
       node.addChild(new Integer(counter), nodeImpl);
       addChildNodes(count + "", nodeImpl, child);
       counter++;
       } else {
       end = true;
       }
       }
       }
      
       private void addChildNodes(String path, TreeNode node, ArrayList properties) {
       boolean end = false;
       int counter = 1;
      
       for (int count = 0; count < child.size(); count++) {
       // String key = path != null ? path + '.' + counter :
       // String.valueOf(counter);
      
       String value = child.get(count);// properties.getProperty(key);
       if (value != null) {
       TreeNodeImpl nodeImpl = new TreeNodeImpl();
       nodeImpl.setData(value);
       node.addChild(new Integer(counter), nodeImpl);
      
       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 TreeNodeImpl();
       addNodes(null, rootNode, treenode);
      
       } catch (Exception e) {
       throw new FacesException(e.getMessage(), e);
       } finally {
      
       }
       }
      
       public void processSelection(NodeSelectedEvent event) {
       HtmlTree tree = (HtmlTree) event.getComponent();
       nodeTitle = (String) tree.getRowData();
       selectedNodeChildren.clear();
       TreeNode currentNode = tree.getModelTreeNode(tree.getRowKey());
       if (currentNode.isLeaf()) {
       selectedNodeChildren.add((String) currentNode.getData());
       } else {
       Iterator<Map.Entry<Object, TreeNode>> it = currentNode
       .getChildren();
       while (it != null && it.hasNext()) {
       Map.Entry<Object, TreeNode> entry = it.next();
       selectedNodeChildren.add(entry.getValue().getData().toString());
       }
       }
       }
      
       public TreeNode getTreeNode() {
       if (rootNode == null) {
       loadTree();
       }
      
       return rootNode;
       }
      
       public String getNodeTitle() {
       return nodeTitle;
       }
      
       public void setNodeTitle(String nodeTitle) {
       this.nodeTitle = nodeTitle;
       }
      
       public ContextMenu getContextMenu() {
       if(contextMenu==null){
       contextMenu=new ContextMenu();
       contextMenu.setId("cm");
       }
       return contextMenu;
       }
      
       public void setContextMenu(ContextMenu contextMenu) {
      
       this.contextMenu = contextMenu;
       }
      
       public String getNodeSelected() {
       return nodeSelected;
       }
      
       public void setNodeSelected(String nodeSelected) {
       this.nodeSelected = nodeSelected;
       }
      
       public void treeListener(ActionEvent event) {
       FacesContext context = FacesContext.getCurrentInstance();
       Application app = context.getApplication();
       getContextMenu().getChildren().clear();
       UIOutput label = (UIOutput) app
       .createComponent(HtmlOutputText.COMPONENT_TYPE);
       label.setId("someLabel");
       label.setValue(nodeSelected);
       HtmlMenuItem mi = (HtmlMenuItem) app
       .createComponent(HtmlMenuItem.COMPONENT_TYPE);
       mi.setId("menuItem");
       mi.getChildren().add(label);
       getContextMenu().getChildren().add(mi);
       }
      
      }
      

      and exception is

      09/11/16 12:37:28 INFO annotation.TomcatAnnotationLifecycleProvider: Creating instance of one.SimpleTreeBean
      09/11/16 12:37:28 ERROR webapp._ErrorPageWriter: An exception occurred
      javax.faces.FacesException: Exception while calling encodeBegin on component : {Component-Path : [Class: org.ajax4jsf.component.AjaxViewRoot,ViewId: /treetest.jsp][Class: javax.faces.component.html.HtmlForm,Id: j_id_jsp_1136468845_1][Class: org.richfaces.component.html.ContextMenu,Id: cm]}
      at javax.faces.component.UIComponentBase.encodeBegin(UIComponentBase.java:599)
      at javax.faces.component.UIComponent.encodeAll(UIComponent.java:245)
      at javax.faces.component.UIComponent.encodeAll(UIComponent.java:257)
      at javax.faces.component.UIComponent.encodeAll(UIComponent.java:257)
      at org.apache.myfaces.application.jsp.JspViewHandlerImpl.actuallyRenderView(JspViewHandlerImpl.java:427)
      at org.apache.myfaces.application.jsp.JspViewHandlerImpl.renderView(JspViewHandlerImpl.java:383)
      at org.jenia.faces.template.handler.ViewHandler.renderView(ViewHandler.java:184)
      at org.ajax4jsf.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:100)
      at org.ajax4jsf.application.AjaxViewHandler.renderView(AjaxViewHandler.java:176)
      at org.apache.myfaces.lifecycle.RenderResponseExecutor.execute(RenderResponseExecutor.java:41)
      at org.apache.myfaces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:140)
      at javax.faces.webapp.FacesServlet.service(FacesServlet.java:155)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
      at org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:178)
      at org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:290)
      at org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:390)
      at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:517)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
      at org.apache.myfaces.webapp.filter.ExtensionsFilter.doFilter(ExtensionsFilter.java:301)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
      at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
      at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
      at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
      at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
      at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
      at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:263)
      at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
      at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:584)
      at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
      at java.lang.Thread.run(Unknown Source)
      Caused by: javax.faces.FacesException: Context menu cannot be attached to the component with id = j_id_jsp_1136468845_1, because a client identifier of the component won't be rendered onto the page. Please, set the identifier.
      at org.richfaces.renderkit.html.ContextMenuRendererBase.ensureParentPresent(ContextMenuRendererBase.java:126)
      at org.richfaces.renderkit.html.ContextMenuRendererBase.doEncodeBegin(ContextMenuRendererBase.java:110)
      at org.ajax4jsf.renderkit.RendererBase.encodeBegin(RendererBase.java:101)
      at javax.faces.component.UIComponentBase.encodeBegin(UIComponentBase.java:596)
      ... 32 more



      Please help me to resolve this exception

        • 2. Re: rich:tree with dynamic menu
          praveen jain Novice

          i am able to solve my problem , i just a small problem please give me the solution
          now i can generate the Dynamic menu but the problem is that
          contaxtMenu is not reflected its value , but when i right click next time it will show the accurate value , but not for the first time
          see the code

          <rich:tree id="treeMain"
           changeExpandListener="#{mainBind.expansionListener}"
           nodeSelectListener="#{mainBind.treeNodeClick}"
           value="#{mainBind.treeNode}" var="node" switchType="ajax"
           binding="#{mainBind.tree}" reRender="contextmenu" >
           <rich:treeNode icon="#{node.imageName}">
           <h:outputText value="#{node.description}" />
          
           <a4j:support event="oncontextmenu"
           oncomplete="#{rich:component('contextmenu')}.doShow(event, {})"
           actionListener="#{mainBind.treeListener}"
           reRender="contentPage,outputPage,exploresummary,pichart,contextmenu">
           <f:setPropertyActionListener value="#{node.description}"
           target="#{mainBind.nodeSelected}" />
           </a4j:support>
          
          
           </rich:treeNode>
          
           </rich:tree>
          
          
           <rich:contextMenu
           id="contextmenu" binding="#{mainBind.contextMenu}"
           submitMode="ajax">
          
           </rich:contextMenu>
          

          and my class is
          public void expansionListener(NodeExpandedEvent event) {
           System.out.println("EXPENDS LISTERNER CALLED ");
           UITree tree = (UITree) event.getComponent();
           TreeNodeWithContent selectedNode=(TreeNodeWithContent) tree.getRowData();
           String nodeTitle = selectedNode.getDescription();
           System.out.println("NODE TITLE IS " + nodeTitle);
           displayMenu(nodeTitle);
           }
          
           public void treeListener(ActionEvent event) {
           System.out.println("EXPENDS LISTERNER CALLED ");
           // UITree tree = (UITree) event.getComponent();
           // String nodeTitle = (String) tree.getRowData();
           System.out.println("NODE TITLE IS "+getNodeSelected());
           displayMenu(getNodeSelected());
           }
          
          


          i want to generate the contextMenu before it displays
          please give me solotuion

          • 3. Re: rich:tree with dynamic menu
            Ilya Shaikovsky Master

             

            <h:form id="form">
             <h:panelGrid columns="2" width="100%" columnClasses="col1,col2">
            
             <rich:tree style="width:300px" nodeSelectListener="#{simpleTreeBean.processSelection}"
             reRender="selectedNode" ajaxSubmitSelection="false" switchType="client"
             value="#{simpleTreeBean.treeNode}" var="item" ajaxKeys="#{null}">
             <rich:treeNode>
             <h:outputText value="#{item}" />
             <a4j:support event="oncontextmenu" disableDefault="true"
             oncomplete="#{rich:component('contextmenu')}.doShow(event, {})"
             reRender="out">
             <a4j:actionparam value="#{item}" name="treeNodeItem"
             assignTo="#{simpleTreeBean.nodeTitle}" actionListener="#{simpleTreeBean.treeListener}"/>
             </a4j:support>
             </rich:treeNode>
             </rich:tree>
             <a4j:outputPanel layout="block" id="out">
             <rich:contextMenu disableDefaultMenu="true" attached="false"
             id="contextmenu" binding="#{simpleTreeBean.menu}"
             submitMode="ajax"/>
             </a4j:outputPanel>
             <h:outputText escape="false" value="Selected Node: #{simpleTreeBean.nodeTitle}" id="selectedNode" />
            
             </h:panelGrid>
            
             </h:form>
            


            and request scoped bean contains

            public class SimpleTreeBean {
             private UIContextMenu menu;
             private TreeNode rootNode = null;
             private List<String> selectedNodeChildren = new ArrayList<String>();
            
             private String nodeTitle;
             private static final String DATA_PATH = "/richfaces/tree/examples/simple-tree-data.properties";
            
             public SimpleTreeBean() {
             menu = (UIContextMenu)FacesContext.getCurrentInstance().getApplication().createComponent(UIContextMenu.COMPONENT_TYPE);
             }
            
             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) {
             TreeNodeImpl nodeImpl = new TreeNodeImpl();
             nodeImpl.setData(value);
             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 TreeNodeImpl();
             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 TreeNode getTreeNode() {
             if (rootNode == null) {
             loadTree();
             }
            
             return rootNode;
             }
            
             public void treeListener(ActionEvent event){
             UIMenuItem item = (UIMenuItem)FacesContext.getCurrentInstance().getApplication()
             .createComponent(UIMenuItem.COMPONENT_TYPE);
             item.setValue(getNodeTitle());
             item.setId(FacesContext.getCurrentInstance().getViewRoot().createUniqueId());
             this.menu.getChildren().clear();
             this.menu.getChildren().add(item);
             }
            
            
            }
            


            works fine for me

            • 4. Re: rich:tree with dynamic menu
              praveen jain Novice

              thanks it is working
              please tell me one more thing how can i add actionListener to perticular menu item.
              which are generated by codes.

              • 5. Re: rich:tree with dynamic menu
                Ilya Shaikovsky Master

                use addActionListener for that.