tags:

views:

61

answers:

2

I've got a JTree, which I am trying to search. I've written a quick recursive search function. The function takes a parent/child node name pair as a string.

private void RecursiveSearch(javax.swing.tree.DefaultMutableTreeNode node, java.util.ArrayList<TreeNode> nodelist, java.lang.String destination, java.lang.String origin) {
     nodelist.add(node);
     Controller.TreeData parentdata = (Controller.TreeData)node.getUserObject();
     for(int i = 0; i < node.getChildCount(); i++) {
        javax.swing.tree.DefaultMutableTreeNode childnode = (javax.swing.tree.DefaultMutableTreeNode)node.getChildAt(i);
        Controller.TreeData childdata = (Controller.TreeData)childnode.getUserObject();
        if (parentdata.GetName().trim().toUpperCase().equals(origin) && childdata.GetName().trim().toUpperCase().equals(destination)) {
            nodelist.add(childnode);
            return;
        }
    }
    // We didn't find it. Recurse.
    for(int i = 0; i < node.getChildCount(); i++) {
        RecursiveSearch((javax.swing.tree.DefaultMutableTreeNode)node.getChildAt(i), nodelist, destination, origin);
    }
    nodelist.remove(node);
}

However, it's not returning values when it should be. I got the root node from the TreeModel and the array starts out empty. I checked the JTree and the TreeModel and neither of them seem to offer any sort of searching functionality. Any suggestions?

Edit: I'm not going to try to explain my original function (it was originally written in another language). But I replaced it with this:

javax.swing.tree.DefaultMutableTreeNode rootnode = (javax.swing.tree.DefaultMutableTreeNode)datatree.getModel().getRoot();
java.util.Enumeration nodeenum = rootnode.breadthFirstEnumeration();
while(nodeenum.hasMoreElements()) {
    javax.swing.tree.DefaultMutableTreeNode nextnode = (javax.swing.tree.DefaultMutableTreeNode)nodeenum.nextElement();
    Controller.TreeData data = (Controller.TreeData)nextnode.getUserObject();
    javax.swing.tree.DefaultMutableTreeNode parentnode = (javax.swing.tree.DefaultMutableTreeNode)nextnode.getParent();
    Controller.TreeData parentdata = (Controller.TreeData)(parentnode.getUserObject());
    if (parentdata.GetName().trim().toUpperCase().equals(origin) && data.GetName().trim().toUpperCase().equals(destination)) {
        datatree.setSelectionPath(new javax.swing.tree.TreePath(treemodel.getPathToRoot(nextnode)));
        return;
    }
}
javax.swing.JOptionPane.showMessageDialog(primaryframe, "Could not find the requested depots");

However, it doesn't actually seem to find anything. I started with the root node, so it should enumerate the whole tree. Fixed the null pointer exception bug in this version.

+1  A: 

I have few suggestions

  • this code won't work if parent,child pair of origin,destination occurs more then once in tree. You can find only first pair and skip its subtree that can contains more occurences
  • i don't know why you add node at the beginning and remove it at the end. Much simpler would be adding both nodes (parent,child) when you find it.
  • you can opitmize you code so if parentnode != origin you don't test all parent,child pairs. If this test parentdata.GetName().trim().toUpperCase().equals(origin) fails skip first loop

Can you provide some example I/O so I will be sure what is your desired result.

The names origin and destination sound like you don't look for immediate child. Can path between origin and destination be longer then 1?

jethro
This is the winrar. I uppercased the data but forgot to uppercase the input I was checking against.
DeadMG
+1  A: 

If you use DefaultMutableTreeNodes wihtin your TreeModel you can simply use breadthFirstEnumeration() or depthFirstEnumeration() to search the tree.

Adamski
How on earth would I use those enumerations to build a tree path so that it can be selected?
DeadMG
Simple - Use a DefaultTreeModel in conjunction with DefaultMutableTreeNode. Locate the TreeNode you want using one of the search methods above and then call DefaultTreeModel's getPathToRoot(TreeNode).
Adamski