Link to home
Start Free TrialLog in
Avatar of allmer
allmerFlag for Türkiye

asked on

JTree programatically selecting a leaf node

Hi Experts,
I constructed a JTree with some data in it.
3 node types: root, ProjectNode, and leaf (string)
I would like to retrieve a leaf's treepath so that I can select it in the JTree.
I can do it for the nodes immediately following root but I couldn't find how to do it for the leaves.

The code below seems to work fine and I get the project node selected.
Now below that are leaves one of which I would like to have selected instead of the project node.

Any ideas?
TreePath tp = projectTree.getNextMatch("someString",0,Position.Bias.Forward);
projectTree.setSelectionPath(tp);
projectTree.expandPath(tp);
//Here I need to get the leaf with the name "x" for instance.
//that one should then be selected instead of the parent as currently
projectTree.setSelectionPath(tp);
projectTree.scrollPathToVisible(tp);
projectTree.repaint();

Open in new window

Avatar of sailingbye
sailingbye
Flag of United Kingdom of Great Britain and Northern Ireland image

Have you tried the JTree.getNextMatch(String, Position.Bias) method? I think it may be what you're looking for.

E.g.

tp = projectTree.getNextMatch("x",Position.Bias.Forward);

Assuming that the name "x" is unique.

Hope this helps.
Avatar of allmer

ASKER

x is unique within the node.

If you check my code above I am using getNextMatch.
Maybe I am missing something here but it only selects the nodes directly following root
and I was not able to select their children.

Does this work for you?
Then my problem must be elsewhere.
A TreePath for a given node encapsulates the path from the root and a list of it children. It doesn't provide direct access to grandchildren and other descendants. In order to access these you need to traverse the sub-tree in the same way that you've traversed the root.

Tree traversal is usually done recursively, but can be done iteratively. Alternatively, if you know in advance (and you're confident this will never change) that your tree will have a depth of three. This can be done without recursion or iteration.
Avatar of allmer

ASKER

Sounds great.
Lines 3 and 5 in the code above show where I am stuck in trying the iterative approach.
tp points to a node which contains the leaves that I am interested in.
The only problem is to get a treepath to one of the children.
How can I do that?
ASKER CERTIFIED SOLUTION
Avatar of sailingbye
sailingbye
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Just to correct myself above:

The a path is independent of both model and component. A model knows how to produce a well formed path and a tree component knows how to interpret one, but a TreePath object is not connected (by reference) to either!

Also, my solution uses a JTree object named tree, but I'm sure you realise that.

Have fun!
Avatar of allmer

ASKER

Unfortunately this didn't work for me for some internal reasons about updating tree and user object which at that point are not really equal :(

Slightly modifying your code did the trick for me however :)

Since the suffix of the node changed I just looked for the prefix et voila.

Thank you for your help!
private TreePath getTreePath() {
        // Get Root Node from the model ...
        TreeNode rootNode  = (TreeNode)projectTree.getModel().getRoot();
        // ... and its path in the tree from the tree.
        TreePath path = new TreePath(rootNode);
        // Iterate over the roots children (projects?)
        for(int i=0; i<rootNode.getChildCount(); i++) {
            TreeNode child = rootNode.getChildAt(i);
            if(child.toString().startsWith(selProject.getName())) { //you have project objects, right?
                path = path.pathByAddingChild(child);
                // Iterate of the project's children (root's grandchildren)
                for(int j=0; j<child.getChildCount(); j++) {
                    TreeNode grandchild = child.getChildAt(j);
                    if(grandchild.toString().equals(selBlastRes.getID())) {
                        path = path.pathByAddingChild(grandchild);
                        return(path);
                    }
                }
                break;
            }
        }
        return(null);
    }

Open in new window

Excellent, we can both get on with some work now :-)