Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 448
Maxim Veksler Avatar asked Mar 31 '09 08:03

Maxim Veksler


2 Answers

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.

like image 84
Maxim Veksler Avatar answered Sep 22 '22 05:09

Maxim Veksler


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() );
like image 26
Alex Colomb Avatar answered Sep 23 '22 05:09

Alex Colomb