2011-11-21 19 views

Respuesta

23

Ampliando la respuesta de @ mKorbel y como se discutió en How to Use Trees, puede buscar TreeModel recursivamente y obtener un TreePath en el nodo resultante. Una vez que tenga el path deseado, es fácil revelarlo en el árbol.

tree.setSelectionPath(path); 
tree.scrollPathToVisible(path); 

Adición: He aquí una manera de "obtener un TreePath."

private TreePath find(DefaultMutableTreeNode root, String s) { 
    @SuppressWarnings("unchecked") 
    Enumeration<DefaultMutableTreeNode> e = root.depthFirstEnumeration(); 
    while (e.hasMoreElements()) { 
     DefaultMutableTreeNode node = e.nextElement(); 
     if (node.toString().equalsIgnoreCase(s)) { 
      return new TreePath(node.getPath()); 
     } 
    } 
    return null; 
} 
+0

my (wild :-) Supongo que "obtener un TreePath" es el corazón del problema, no ciencia espacial, pero no hay ningún ejemplo de hacerlo en el tutorial (o que soy ciego, un no-cero probabilidad ) – kleopatra

+0

@kleopatra: Buen punto; más arriba. – trashgod

1

Aquí es un ejemplo de cómo desplazarse a través de un árbol en una búsqueda:

import java.awt.BorderLayout; 
    import java.awt.event.ActionEvent; 
    import java.awt.event.ActionListener; 
    import java.util.ArrayList; 
    import java.util.Enumeration; 
    import java.util.List; 

    import javax.swing.JButton; 
    import javax.swing.JFrame; 
    import javax.swing.JScrollPane; 
    import javax.swing.JTextField; 
    import javax.swing.JTree; 
    import javax.swing.tree.DefaultMutableTreeNode; 
    import javax.swing.tree.DefaultTreeModel; 
    import javax.swing.tree.TreePath; 

    public class TreeDemo extends JFrame implements ActionListener{ 
     private static final long serialVersionUID = 1L; 
     public JTree tree; 
     public JButton button; 
     public JTextField text; 

     public TreeDemo() { 

      button = new JButton("Enter search text below and click"); 
      text = new JTextField(); 


      button.addActionListener(this); 

      tree = new JTree(); 
      DefaultMutableTreeNode root = new DefaultMutableTreeNode("Deck"); 
      DefaultMutableTreeNode itemClubs= new DefaultMutableTreeNode("Clubs"); 
      addAllCard(itemClubs); 
      root.add(itemClubs); 

      DefaultMutableTreeNode itemDiamonds = new DefaultMutableTreeNode("Diamonds"); 
      addAllCard(itemDiamonds); 
      root.add(itemDiamonds); 

      DefaultMutableTreeNode itemSpades = new DefaultMutableTreeNode("Spades"); 
      addAllCard(itemSpades); 
      root.add(itemSpades); 

      DefaultMutableTreeNode itemHearts = new DefaultMutableTreeNode("Hearts"); 
      addAllCard(itemHearts); 
      root.add(itemHearts); 

      DefaultTreeModel treeModel = new DefaultTreeModel(root); 
      tree = new JTree(treeModel); 

      JScrollPane scrollPane = new JScrollPane(tree); 
      getContentPane().add(scrollPane, BorderLayout.CENTER); 
      getContentPane().add(button, BorderLayout.NORTH); 
      getContentPane().add(text, BorderLayout.SOUTH); 

      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
      setSize(375, 400);  
     } 

     public void addAllCard(DefaultMutableTreeNode suit) { 
      suit.add(new DefaultMutableTreeNode("Ace")); 
      suit.add(new DefaultMutableTreeNode("Two")); 
      suit.add(new DefaultMutableTreeNode("Three")); 
      suit.add(new DefaultMutableTreeNode("Four")); 
      suit.add(new DefaultMutableTreeNode("Five")); 
      suit.add(new DefaultMutableTreeNode("Six")); 
      suit.add(new DefaultMutableTreeNode("Seven")); 
      suit.add(new DefaultMutableTreeNode("Eight")); 
      suit.add(new DefaultMutableTreeNode("Nine")); 
      suit.add(new DefaultMutableTreeNode("Ten")); 
      suit.add(new DefaultMutableTreeNode("Jack")); 
      suit.add(new DefaultMutableTreeNode("Queen")); 
      suit.add(new DefaultMutableTreeNode("King")); 
     } 

     public final DefaultMutableTreeNode findNode(String searchString) { 

      List<DefaultMutableTreeNode> searchNodes = getSearchNodes((DefaultMutableTreeNode)tree.getModel().getRoot()); 
      DefaultMutableTreeNode currentNode = (DefaultMutableTreeNode)tree.getLastSelectedPathComponent(); 

      DefaultMutableTreeNode foundNode = null; 
      int bookmark = -1; 

      if(currentNode != null) { 
       for(int index = 0; index < searchNodes.size(); index++) { 
        if(searchNodes.get(index) == currentNode) { 
         bookmark = index; 
         break; 
        } 
       } 
      } 

      for(int index = bookmark + 1; index < searchNodes.size(); index++) {  
       if(searchNodes.get(index).toString().toLowerCase().contains(searchString.toLowerCase())) { 
        foundNode = searchNodes.get(index); 
        break; 
       } 
      } 

      if(foundNode == null) { 
       for(int index = 0; index <= bookmark; index++) {  
        if(searchNodes.get(index).toString().toLowerCase().contains(searchString.toLowerCase())) { 
         foundNode = searchNodes.get(index); 
         break; 
        } 
       } 
      } 
      return foundNode; 
     } 

     private final List<DefaultMutableTreeNode> getSearchNodes(DefaultMutableTreeNode root) { 
      List<DefaultMutableTreeNode> searchNodes = new ArrayList<DefaultMutableTreeNode>(); 

      Enumeration<?> e = root.preorderEnumeration(); 
      while(e.hasMoreElements()) { 
       searchNodes.add((DefaultMutableTreeNode)e.nextElement()); 
      } 
      return searchNodes; 
     } 

     public static void main(String[] args) { 
      TreeDemo app = new TreeDemo(); 
      app.setVisible(true); 


     } 


     public void actionPerformed(ActionEvent e) { 
      String search = text.getText(); 
       if(search.trim().length() > 0) { 

       DefaultMutableTreeNode node = findNode(search);     
       if(node != null) { 
        TreePath path = new TreePath(node.getPath()); 
        tree.setSelectionPath(path); 
        tree.scrollPathToVisible(path); 
       } 
      } 
     } 
    } 
+0

Buen ejemplo; también considere 'text.addActionListener (this)'; ver también [* Hilos iniciales *] (http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html). – trashgod

2

Asumo que quiere decir que usted quiere encontrar un nodo con una cadena en particular, ¿verdad? Las otras respuestas explican las formas de hacer esto usando el enfoque de enumeración ... (y estoy seguro de que todos saben que en el mundo real también tendrías que atender la posibilidad de que más de un nodo tenga la cadena buscada, etc.)

Pero hay otras maneras potencialmente más sexys de hacerlo. Por ejemplo, si coloca todos los nodos en un collection de algún tipo (ArrayList, etc. *) a medida que se insertaron en el árbol (y los eliminó a medida que se eliminaron, incluida la eliminación explícita de todos sus descendientes) ... y si también se implementaron cosas para que dos nodos se consideraran "iguales" si tuvieran el mismo resultado de toString (o implementaron un Comparator que lo hizo), entonces podría sacar fácilmente el nodo (o nodos) real en el ArrayList que coincida, y luego ir

tree.expandPath(new TreePath(node_found.getPath()) 

Uno de los puntos de los árboles es que realmente es el camino al nodo (a veces llamado el "migas de pan"), que es la verdadera "identidad" de cualquier nodo dado. En cuanto a los que se muestran String valores, esto significa que usted podría tener, en el mismo árbol:

ruta: "Pedro" - "Piper" - "escabeche" - "pimienta"
trayectoria: "Las especialidades culinarias" - "especias "- 'pimienta'
ruta: 'Mis favoritos' - 'comida' - 'condimentos' - 'pimienta'

y así dice que quiere buscar, y luego seleccionar o resaltar, uno de estos" pimienta "nodos ... no es realmente muy eficiente tener un enfoque de enumeración de" fuerza bruta "para cada uno de los elementos a lo largo de esta ruta (cuanto más grande es el árbol, peor es el problema, por supuesto).

Usando mi sugerencia, se vuelve bastante fácil: solo divida su ruta de "migas de pan", comenzando desde la raíz o donde sea, y luego, cuando profundice en el árbol, use node.isNodeDescendant() en los nodos "superiores" (es decir, aquellos más lejos de la raíz) que ya ha encontrado (aquí, los 3 nodos "pimiento"): si quisiera la primera ruta arriba, primero encontraría el nodo "Peter", y luego inmediatamente el único nodo "pimiento" que podría satisfacer la prueba isNodeDescendant arrojaría todo el camino que estás buscando.

* Alguna forma de recolección de hash sería aún más eficiente, por supuesto. Pero esto es una consideración solo si tienes muchos miles, o más, nodos en tu árbol.

Cuestiones relacionadas