2011-09-07 15 views
5

Tengo un Jtree y 2 botones para seleccionar y anular la selección de todos los nodos. Hice un intento de esta manera:JTree: Seleccionar todos los nodos de forma programática

selectAll = new JButton("Select all"); 
selectAll.addActionListener(new ActionListener(){ 
     @Override 
     public void actionPerformed(ActionEvent e) { 
       int row = 0; 
       while (row < curvesTree.getRowCount()) 
       { 
        curvesTree.expandRow(row); 
        row++; 
       } 
      int entradasTree = curvesTree.getRowCount(); 
      for(int i=0; i<entradasTree; i++){ 
       TreePath path = curvesTree.getPathForRow(i); 
       curvesTree.setSelectionPath(path); 
      } 
     } 
    }); 

     unselectAll = new JButton("Unselect all"); 
     unselectAll.addActionListener(new ActionListener(){ 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       curvesTree.clearSelection(); 
      } 
     }); 

El botón de anular la selección parece estar funcionando, pero el selecto de todo, sólo se expande el JTree y selecciona el último nodo. Creo que cada vez que se selecciona un nodo de forma programática, estoy deseleccionando el anterior.

JTree está configurado de esta manera:

curvesTree = new JTree(rootNode); 
curvesTree.setExpandsSelectedPaths(true); 
curvesTree.getSelectionModel().setSelectionMode(TreeSelectionModel. 
        DISCONTIGUOUS_TREE_SELECTION); 

Respuesta

6

la anule la selección se debe a que se está configurando una nueva ruta de la selección en lugar de añadir. En el bucle, después de expandirse, en lugar hacerlo

curvesTree.addSelectionPath(...) 

EDITAR

API de lectura siempre es instructivo, incluso después de años ;-) Sólo se encontró un método simper tanto, lo que deja todo el trabajo en el árbol:

tree.setSelectionInterval(0, tree.getRowCount()); 
+1

captura excelente, cómo se hizo ... +1 – mKorbel

+0

Gracias, he estado buscando para ese método media mañana :) –

0

sí que es posible, por ejemplo:

import java.awt.Dimension; 
import javax.swing.*; 
import javax.swing.event.*; 
import javax.swing.tree.*; 

public class TreeWithMultiDiscontiguousSelections { 

    public static void main(String[] argv) { 
     JTree tree = new JTree(); 
     tree.getSelectionModel().setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION); 
     int treeSelectedRows[] = {3, 1}; 
     tree.setSelectionRows(treeSelectedRows); 
     TreeSelectionListener treeSelectionListener = new TreeSelectionListener() { 

      @Override 
      public void valueChanged(TreeSelectionEvent treeSelectionEvent) { 
       JTree treeSource = (JTree) treeSelectionEvent.getSource(); 
       System.out.println("Min: " + treeSource.getMinSelectionRow()); 
       System.out.println("Max: " + treeSource.getMaxSelectionRow()); 
       System.out.println("Lead: " + treeSource.getLeadSelectionRow()); 
       System.out.println("Row: " + treeSource.getSelectionRows()[0]); 
      } 
     }; 
     tree.addTreeSelectionListener(treeSelectionListener); 
     JFrame frame = new JFrame("JTree With Multi-Discontiguous selection"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.add(new JScrollPane(tree)); 
     frame.setPreferredSize(new Dimension(380, 320)); 
     frame.setLocation(150, 150); 
     frame.pack(); 
     frame.setVisible(true); 
    } 

    private TreeWithMultiDiscontiguousSelections() { 
    } 
} 
+0

fragmento de código aleatorio de nuevo ;-) – kleopatra

0

Me gustaría agregar a la respuesta de kleopatra (basado en mis propios dolores de crecimiento).

En mi problema particular, necesitaba agregar una opción de menú "Seleccionar todos los niños" al menú emergente del nodo JTree. Por lo tanto, esta solución se aplica a todos los hijos de un nodo seleccionado.

TreeNode selectedNode = tree.getSelectionPath().getLastPathComponent(); 
// Expand tree from selected node... 
List<TreePath> paths = new ArrayList<TreePath>(); 
determineTreePaths(selectedNode, paths); // Recursive method call... 

TreePath[] treePaths = new TreePath[paths.size()]; 
Iterator<TreePath> iter = paths.iterator(); 

for (int i = 0; iter.hasNext(); ++i) 
{ 
    treePaths[i] = iter.next(); 
} 

if (paths.size() > 0) 
{ 
    TreePath firstElement = paths.get(0); 
    setSelectionPath(firstElement); 
    scrollPathToVisible(firstElement); 
}  

Se necesita la determineTreePaths(selectedNode, paths) llamada recursiva para recorrer el árbol desde el nodo seleccionado hasta el final abajo a los nodos hoja. Esta solución funciona independientemente de la profundidad (a lo mejor de mi conocimiento). Lo que no puedo decir es que es la solución más eficiente. Cualquier persona con una mejor solución, no dude en publicar una solución diferente o editar esta.

La implementación del método es el siguiente:

private void determineTreePaths(TreeNode currentNode, List<TreePath> paths) 
{ 
    paths.add(new TreePath(((DefaultTreeModel) getDefaultTreeModel()).getPathToRoot(currentNode)); 

    // Get all of my Children 
    Enumeration<?> children = currentNode.children(); 

    // iterate over my children 
    while (children.hasMoreElements()) 
    { 
     TreeNode child = (TreeNode) children.nextElement(); 
     determineTreePaths(child, paths); 
    } 
} 
Cuestiones relacionadas