Search code examples
javaswinguser-interfacejtree

how to set JTree "ctrl" selection mode to be always enabled


I have a JTree that implements multi selection logic.

This works great when I do all my selections using the mouse + Ctrl key pressed. If user makes selections with the Ctrl key unpressed it breaks my logic.

I can't really see why it breaks but I think that a possible solution is to always indicate the TreeSelectionModel that the selection has been make with the Ctrl key pressed.

What would you suggest?


Solution

  • I think I've found the solution

    You will need to extend JTree and DefaultTreeSelectionModel.

    JTree relevant methods:

    /////////////////////////////////////////////////////
    /////////////////////////////////////////////////////
    /// 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 relevant methods :

    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.