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?
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.
Another solution would be to simply extend BasicTreeUI and change the selection behavior to suit your needs:
public class MultiSelectionTreeUI extends BasicTreeUI
{
    @Override
    protected boolean isToggleSelectionEvent( MouseEvent event )
    {
        return SwingUtilities.isLeftMouseButton( event );
    }
}
And then set that ui on your JTree:
JTree tree = new JTree();
tree.setUI( new MultiSelectionTreeUI() );
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With