2009-03-31 10 views
5

J'ai un JTree qui implémente une logique de sélection multiple.comment régler le mode de sélection JTree "ctrl" pour qu'il soit toujours activé

Cela fonctionne très bien lorsque je fais toutes mes sélections en utilisant la touche + Ctrl enfoncée. Si l'utilisateur fait des sélections avec la touche Ctrl non enfoncée, cela casse ma logique.

Je ne peux pas vraiment voir pourquoi il casse mais je pense qu'une solution possible est d'indiquer toujours le TreeSelectionModel que la sélection a été faite avec la touche Ctrl enfoncée.

Que suggéreriez-vous?

+0

besoin de clarifier quelques petites choses . Donc, CTRL + clic gauche vous permet de sélectionner plusieurs nœuds dans le jtree, mais lorsque vous cliquez simplement dessus, vous en sélectionnez un seul. Donc, ce que vous voulez, c'est que l'arbre fonctionne comme Ctrl est toujours pressé et continuez à ajouter des sélections sur chaque clic? – willcodejavaforfood

+0

@willcodejavaforfood - Exactement. –

Répondre

5

Je pense avoir trouvé la solution

Vous devez étendre DTree et DefaultTreeSelectionModel.

JTree méthodes pertinentes:

///////////////////////////////////////////////////// 
///////////////////////////////////////////////////// 
/// Implement selection using "adding" only logic. // 
///////////////////////////////////////////////////// 
///////////////////////////////////////////////////// 

@Override 
public void setSelectionPath(TreePath path) { 

    System.out.println("MLDebugJTree: setSelectionPath(" + path + ")"); 

    addSelectionPath(path); 

    return; 
    //super.setSelectionPath(path); 
} 

@Override 
public void setSelectionPaths(TreePath[] paths) { 

    System.out.println("MLDebugJTree: setSelectionPaths(" + paths + ")"); 

    addSelectionPaths(paths); 

    return; 
} 

@Override 
public void setSelectionRow(int row) { 

    System.out.println("MLDebugJTree: setSelectionRow(" + row + ")"); 

    addSelectionRow(row); 

    return; 
    //super.setSelectionRow(row); 
} 

@Override 
public void setSelectionRows(int[] rows) { 

    System.out.println("MLDebugJTree: setSelectionRows(" + rows + ")"); 

    addSelectionRows(rows); 

    return; 
    //super.setSelectionRows(rows); 
} 

DefaultSelectionModel méthodes pertinentes:

package com.ml.tree2.model.impl; 

import javax.swing.tree.DefaultTreeSelectionModel; 
import javax.swing.tree.TreePath; 

public class MLTreeSelectionModel extends DefaultTreeSelectionModel { 
private static final long serialVersionUID = -4270031800448415780L; 

@Override 
public void addSelectionPath(TreePath path) { 
    // Don't do overriding logic here because addSelectionPaths is ultimately called. 
    super.addSelectionPath(path); 
} 

@Override 
public void addSelectionPaths(TreePath[] paths) { 
    if(paths != null) { 
     for(TreePath path : paths) { 

      TreePath[] toAdd = new TreePath[1]; 
      toAdd[0] = path; 

      if (isPathSelected(path)) { 
       // If path has been previously selected REMOVE THE SELECTION. 
       super.removeSelectionPaths(toAdd); 
      } else { 
       // Else we really want to add the selection... 
       super.addSelectionPaths(toAdd); 
      } 
     } 
    } 
} 

HTH.

+0

merci, je ne peux pas assez l'emporter, cela m'a sauvé beaucoup de recherche! –

2

Une autre solution consisterait à étendre simplement BasicTreeUI et modifier le comportement de sélection en fonction de vos besoins:

public class MultiSelectionTreeUI extends BasicTreeUI 
{ 

    @Override 
    protected boolean isToggleSelectionEvent(MouseEvent event) 
    { 
     return SwingUtilities.isLeftMouseButton(event); 
    } 
} 

Et puis réglez que ui sur votre DTree:

JTree tree = new JTree(); 
tree.setUI(new MultiSelectionTreeUI()); 
+0

Vous allez revenir à 'BasicUI' au lieu d'un autre L & F (p.ex.' WindowsTreeUI') avec cette solution, mais c'est la plus propre. –

Questions connexes