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

    rich:tree with dynamic menu

    ipraveenjain

      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

        • 1. Re: rich:tree with dynamic menu
          nbelaevski
          • 2. Re: rich:tree with dynamic menu
            ipraveenjain

            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

               

              <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
                ipraveenjain

                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

                  use addActionListener for that.