how to set JTree "ctrl" selection mode to be always enabled
Asked Answered
D

2

5

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?

Downpipe answered 31/3, 2009 at 8:24 Comment(2)
Need to clarify a few things. So CTRL+left click lets you select multiple nodes in the jtree, but when just left clicking it only selects one? So what you want is to have the tree work as ctrl is always pressed and just keep adding selections on each click?Plexiform
@Plexiform - Exactly.Downpipe
D
5

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.

Downpipe answered 31/3, 2009 at 15:26 Comment(1)
thanks, I can't upvote this enough, this saved me loads of searching!Bozovich
D
3

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() );
Dilatant answered 13/5, 2013 at 14:54 Comment(1)
You will go back to BasicUI instead of another L&F (p.ex. WindowsTreeUI) with this solution, but it is the cleanest one.Viscountcy

© 2022 - 2024 — McMap. All rights reserved.