2010-08-12 3 views
1

J'ai un JTree, que j'essaie de rechercher. J'ai écrit une fonction de recherche rapide et récursive. La fonction prend une paire de noms de nœuds parent/enfant en tant que chaîne.Recherche d'un JTree

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); 
} 

Cependant, il ne renvoie pas de valeurs lorsqu'il devrait l'être. J'ai reçu le nœud racine du TreeModel et le tableau commence vide. J'ai vérifié le JTree et le TreeModel et aucun d'eux ne semble offrir une sorte de fonctionnalité de recherche. Aucune suggestion?

Edit: Je ne vais pas essayer d'expliquer ma fonction d'origine (il a été écrit à l'origine dans une autre langue). Mais je l'ai remplacé par ceci:

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"); 

Cependant, il ne semble pas vraiment trouver quelque chose. J'ai commencé avec le nœud racine, donc il devrait énumérer l'arbre entier. Correction du bogue de l'exception du pointeur nul dans cette version.

+0

Retour des valeurs? C'est une fonction "vide". Est-ce que vous essayez de le faire modifier le JTree d'une certaine façon? Quel comportement essayez-vous d'atteindre? –

+0

Pourquoi ajouter tous les éléments au départ et les supprimer à la fin? – jethro

+0

Si j'étais vous je voudrais essayer d'utiliser le débogueur. Etes-vous sûr que data.GetName(). Trim(). ToUpperCase() renvoie ce que vous attendez et transmet comme arguments (origine, destination)? Avez-vous vérifié si tous les nœuds sont visités? Êtes-vous sûr de ne pas modifier la structure ou les données d'un autre thread? – jethro

Répondre

2

J'ai quelques suggestions

  • ce code ne fonctionnera pas si le parent, la paire d'enfants d'origine, la destination se produit plus d'une fois dans l'arbre. Vous ne pouvez trouver que la première paire et sauter sa sous-arborescence qui peut contenir plus d'occurrences
  • Je ne sais pas pourquoi vous ajoutez un noeud au début et le supprimez à la fin. Beaucoup plus simple serait d'ajouter les deux nœuds (parent, enfant) quand vous le trouvez.
  • vous pouvez opitmize vous le code si parentnode! = Origin vous ne testez pas toutes les paires parent-enfant. Si ce test parentdata.GetName().trim().toUpperCase().equals(origin) échoue ignorer la première boucle

Pouvez-vous fournir quelques exemples d'E/S afin que je sois sûr quel est le résultat souhaité.

Les noms origin et destination sonnent comme si vous ne recherchiez pas d'enfant immédiat. Le chemin entre origin et destination peut-il être plus long que 1?

+0

Ceci est le winrar. J'ai mis en majuscules les données mais j'ai oublié de mettre en majuscules l'entrée que je vérifiais. – Puppy

2

Si vous utilisez DefaultMutableTreeNode avec votre TreeModel, vous pouvez simplement utiliser breadthFirstEnumeration() ou depthFirstEnumeration() pour rechercher l'arbre.

+0

Comment diable pourrais-je utiliser ces énumérations pour construire un chemin d'arbre afin qu'il puisse être sélectionné? – Puppy

+0

Simple - Utilisez un DefaultTreeModel en conjonction avec DefaultMutableTreeNode. Recherchez le TreeNode souhaité en utilisant l'une des méthodes de recherche ci-dessus, puis appelez getPathToRoot (TreeNode) de DefaultTreeModel. – Adamski