5 Replies Latest reply on Feb 29, 2012 5:03 PM by Dave Mulligan

    How do I access the actual objects in a RichFaces 4 tree?

    Dave Mulligan Newbie

      Hi all,

       

      I'm really struggling with what seems like a simple problem.  I've built a rich:tree component, and it renders just fine.  But, when I select a node, I cannot work out how to access the object that was originally put there.  For example, I have a tree of Product objects, arranged into ProductFamilies.  I'd like to work out how to get to the Product object when I click on it.  Right now I am getting a reference to the SwingTreeNodeImpl object, which must be the runtime class of the node.  I feel I must be missing something obvious, but I haven't worked out what it is, despite having tried almost every suggestion I can find.

       

      Here is my tree definition (some node types left out for brevity):

      {code}

      <rich:tree

           id="sku"

           nodeType="#{node.type}"

           var="node"

           value="#{treeBean.rootNodes}"

           toggleType="ajax"

           selectionType="ajax"

           selectionChangeListener="#{treeBean.selectionChanged}"

      >

           <rich:treeNode type="ProductFamily">

                #{node.displayString}

           </rich:treeNode>

           <rich:treeNode type="Product">

                #{node.displayString}

           </rich:treeNode>

      </rich:tree>

      {code}

       

      Here is the part of my TreeBean class that defines the root nodes:

       

      {code}

              

                private List<TreeNode> rootNodes = new ArrayList<TreeNode>();

       

       

                public TreeBean() {

                          for (ProductFamily pf : ProductFamily.values()) {

                                    rootNodes.add(pf);

                          }

                }

       

      {code}

       

      and some parts of the ProductFamily class that seem relevant:

       

      {code}

      public enum ProductFamily implements TreeNode {

       

      ...

       

      public List<Product> getProducts() {

           return getDAO().getAllProductsinFamily(this);

      }

       

      ...

       

      @Override

      public Enumeration<Product> children() {

           return Collections.enumeration(getProducts());

      }

       

        @Override

      public boolean getAllowsChildren() {

             return true;

      }

       

      ... and so on ...

      {code}

       

      But, when I run the code I plagiarized from here (http://richfaces-showcase.appspot.com/richfaces/component-sample.jsf?demo=tree&skin=blueSky), I end up with an exception that the SwingTreeNodeImpl class doesn't have the method I'm trying to call when I ask for "name".  Which is, of course, perfectly correct, but how do I get my Product or ProductFamily out of the SwingTreeNodeImpl? 

       

      Thanks, and I really hope I haven't missed anything obvious: this is my first project working with Richfaces.

       

      - Dave

        • 1. Re: How do I access the actual objects in a RichFaces 4 tree?
          Maheswara Sunkara Novice

          did you check the 'selectionChangeListener' in <rich:tree tag and 'selectionChanged' method of treeBean (in showcase code), where you are getting current selection.

          • 2. Re: How do I access the actual objects in a RichFaces 4 tree?
            Dave Mulligan Newbie

            Hi there,

             

            Yes, I did.  Here's my current implementation of the TreeBean.selectionChanged() method:

             

             

            {code}

            public void selectionChanged(TreeSelectionChangeEvent event) {

                                System.out.println("It changed!");

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

                                Object currentSelectionKey = selection.get(0);

                                System.out.println("currentSelectionKey: " + currentSelectionKey);

                               

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

                                Object storedKey = tree.getRowKey();

                                System.out.println("storedKey: " + storedKey);

                               

                                Object selected = tree.getRowData();

                                System.out.println("selected: " + selected);

                               

                                currentSelection = (TreeNode) tree.getRowData();

                                System.out.println("currentSelection: " + currentSelection);

             

                                tree.setRowKey(storedKey);

                      }

            {code}

             

            and here is the output I get from all those print statements:

             

            {code}

            INFO: It changed!

            INFO: currentSelectionKey: org.richfaces.model.SequenceRowKey[0, 0]

            INFO: storedKey: null

            INFO: selected: SwingTreeNodeImpl{data=null}

            INFO: currentSelection: SwingTreeNodeImpl{data=null}

            {code}   

                    

            Which of these lines should give me access to my Product or ProductFamily document?  Am I missing a step in the creation of the nodes?

             

            Thanks

             

            Dave

            • 3. Re: How do I access the actual objects in a RichFaces 4 tree?
              Maheswara Sunkara Novice

              if you followed the same pattern from showcase 'currentSelection' object should give you the ProductFamily  and Product details.

               

              Why did you create ProductFamily as enum type? (public enum ProductFamily implements TreeNode)

               

              You didn't extend ProductFamily from NamedNode (as in showcase) so you will not be having 'name' property unless you have 'name' property on ProductFamily..

               

              I doubt there is something wrong with Productfamily and Product classes..

               

              Are you able to see the full tree structure properly?

              1 of 1 people found this helpful
              • 4. Re: How do I access the actual objects in a RichFaces 4 tree?
                Dave Mulligan Newbie

                ProductFamily is an enum because there are only a very small number of values.

                 

                I didn't extend NamedNode because it didn't seem to add much: my actual classes already implemented a PrettyPrinter interface that defines a getDisplayString() method.  The full tree displays perfectly, with the nodes defined as

                <rich:treeNode type="ProductFamily">

                     #{node.displayString}

                </rich:treeNode>

                but, if I ask for treeBean.currentSelection.displayString, I get an error that SwingTreeNodeImpl doesn't have a method called getDisplayString().

                 

                So it seems that when rendering the tree, my classes are being used, but when I select a node, they are not, and I'm getting the class type of the default node implementation.

                 

                I've attached my ProductFamily.java and Product.java classes: I would love for the answer to be that there is something simple wrong in there.

                 

                Thanks again for your time.

                 

                - Dave

                • 5. Re: How do I access the actual objects in a RichFaces 4 tree?
                  Dave Mulligan Newbie

                  Ah.  How embarrassing.

                   

                  My selectionChanged() listener method was missing a line:

                   

                  tree.setRowKey(currentSelectionKey);

                   

                  Turns out taht that line is quite important.  Working perfectly now.  Thanks for all the help: you pushed me in the right direction with the comment "If you followed the same pattern..." which made me go back and check my code one more time.

                   

                  - Dave