Search code examples
gwttreecell

Open GWT cell tree to specific node


I have a file browser type application consisting of a CellTree displaying the hierarchy and a browser pane showing the contents of the current node.

The application has to handle hierarchies which may be too large for the CellTree to handle effectively, so the location shown in the browser pane is not strongly coupled to the open nodes in the tree.

I wish to implement a button which will open the current browse location in the CellTree. My server side data model has parent/child references on all objects so obtaining the hierarchy is a simple matter, but I am struggling with how to apply this to the tree.

This is my current attempt, it is a method on the widget which contains my tree, and is called from the reciever. The RecordTreeLevel objects each represent a level in the tree.

public void navigateTo(List<RecordTreeLevelProxy> hierarchy) {
    TreeNode currentNode = tree.getRootTreeNode();

    ListIterator iter = hierarchy.listIterator(hierarchy.size());

    while (iter.hasPrevious()){
        RecordTreeLevelProxy level = (RecordTreeLevelProxy) iter.previous();
        Integer nodeIndex = locateNode(level.getUniqueRef(), currentNode);
        if (nodeIndex != null){
            currentNode = currentNode.setChildOpen(nodeIndex, true, true);
        }
    }
}

This doesn't work, because the loop completes in its entirity before the children are added to any of the nodes. Therefore the first level node opens as it should, but doesn't have any children when the loop comes around the second time.

I can't help but feel that I'm missing something obvious, or doing this in the wrong way, but I can't see it. Any help much apprieciated (even if it's to say "don't be silly, you can't do it that way)


Solution

  • Your code should work if you populate the data synchronously from your TreeViewModel (provided locateNode does what I think it does, i.e. iterate over currentNode.getChildValue(i) with i between 0 and currentNode.getChildCount()).

    What I'm doing in a similar scenario (I'm actually doing it with a CellBrowser) is that I preload the cache (I'm caching the response for the various branches of the tree) using the hierarchy to the selected node, and then run code very similar to yours. The TreeViewModel runs synchronously if the value is in the cache, asynchronously otherwise (asking the server for the children of the opened node).

    For example, for the following tree:

    - A
      +- A1
         +- A1a
      +- A2
         +- A2a
         +- A2b
    - B
      +- B1
      +- B2
    

    If the A2a node should be pre-selected, I start by load the root branch, the A branch, then the A2 branch:

    <root> -> [ A, B ]
    A      -> [ A1, A2 ]
    A2     -> [ A2a, A2b ]
    

    That way, I'm sure my TreeViewModel will run synchronously for the nodes <root>, A and A2.

    And then only I run the setChildOpen code. Because the TreeViewModel is synchronous for these nodes, setChildOpen returns a non-null value.