2010-08-12 3 views
1

У меня есть JTree, который я пытаюсь выполнить. Я написал функцию быстрого рекурсивного поиска. Функция принимает пару имен родительского/дочернего узлов в виде строки.Поиск 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); 
} 

Однако, это не возвращает значения, когда это должно быть. Я получил корневой узел из TreeModel, и массив начинает пустым. Я проверил JTree и TreeModel, и ни один из них не предлагает каких-либо функций поиска. Какие-либо предложения?

Редактировать: Я не собираюсь пытаться объяснить мою оригинальную функцию (она была первоначально написана на другом языке). Но я заменил его на это:

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

Однако, похоже, он ничего не нашел. Я начал с корневого узла, поэтому он должен перечислить все дерево. Исправлена ​​ошибка с ошибкой нулевого указателя в этой версии.

+0

Возвращаемые значения? Это функция 'void'. Вы пытаетесь каким-то образом модифицировать JTree? Какое поведение вы пытаетесь достичь? –

+0

Почему вы добавляете каждый элемент в начале и удаляете его в конце? – jethro

+0

Если бы я был вами, я бы попытался использовать отладчик. Вы уверены, что data.GetName(). Trim(). ToUpperCase() возвращает то, что вы ожидаете и передаете в качестве аргументов (происхождение, назначение)? Вы проверили, посещаются ли все узлы? Вы уверены, что не изменяете структуру или данные в другом потоке? – jethro

ответ

2

У меня есть несколько предложений

  • этот код не будет работать, если родитель, ребенок пара происхождения, назначение происходит более чем один раз в дереве. Вы можете найти только первую пару и пропустить ее поддерево, которое может содержать больше случаев.
  • Я не знаю, почему вы добавляете узел в начале и удаляете его в конце. Гораздо проще было бы добавить оба узла (родительский, дочерний), когда вы его найдете.
  • вы можете оформить код, чтобы, если parentnode! = Origin, вы не проверяете все родительские, дочерние пары. Если этот тест parentdata.GetName().trim().toUpperCase().equals(origin) не прошел первую петлю

Можете ли вы привести пример ввода-вывода, поэтому я буду уверен, какой у вас желаемый результат.

Имена origin и destination звучат так, будто вы не ищете немедленного ребенка. Может ли путь между origin и destination быть длиннее 1?

+0

Это винрар. Я заштриховал данные, но забыл в верхнем регистре ввод, который я проверял. – Puppy

2

Если вы используете DefaultMutableTreeNode сек wihtin ваш TreeModel вы можете просто использовать breadthFirstEnumeration() или depthFirstEnumeration() искать дерево.

+0

Как бы я использовал эти перечисления для построения пути дерева, чтобы его можно было выбрать? – Puppy

+0

Простой - используйте DefaultTreeModel в сочетании с DefaultMutableTreeNode. Найдите нужный TreeNode, используя один из методов поиска выше, а затем вызовите getPathToRoot DefaultTreeModel (TreeNode). – Adamski