I have a JTree that implements multi selection logic.
我有一个实现多选逻辑的JTree。
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.
当我按下鼠标+ Ctrl键进行所有选择时,这非常有用。如果用户在按下Ctrl键的情况下进行选择,则会破坏我的逻辑。
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.
我真的不明白为什么它会中断但我认为可能的解决方案是始终指示TreeSelectionModel已按下Ctrl键进行选择。
What would you suggest?
你会建议什么?
2 个解决方案
#1
I think I've found the solution
我想我找到了解决方案
You will need to extend JTree and DefaultTreeSelectionModel.
您将需要扩展JTree和DefaultTreeSelectionModel。
JTree relevant methods:
JTree相关方法:
/////////////////////////////////////////////////////
/////////////////////////////////////////////////////
/// 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 :
DefaultSelectionModel相关方法:
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.
#2
Another solution would be to simply extend BasicTreeUI and change the selection behavior to suit your needs:
另一个解决方案是简单地扩展BasicTreeUI并更改选择行为以满足您的需求:
public class MultiSelectionTreeUI extends BasicTreeUI
{
@Override
protected boolean isToggleSelectionEvent( MouseEvent event )
{
return SwingUtilities.isLeftMouseButton( event );
}
}
And then set that ui on your JTree:
然后在你的JTree上设置ui:
JTree tree = new JTree();
tree.setUI( new MultiSelectionTreeUI() );
#1
I think I've found the solution
我想我找到了解决方案
You will need to extend JTree and DefaultTreeSelectionModel.
您将需要扩展JTree和DefaultTreeSelectionModel。
JTree relevant methods:
JTree相关方法:
/////////////////////////////////////////////////////
/////////////////////////////////////////////////////
/// 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 :
DefaultSelectionModel相关方法:
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.
#2
Another solution would be to simply extend BasicTreeUI and change the selection behavior to suit your needs:
另一个解决方案是简单地扩展BasicTreeUI并更改选择行为以满足您的需求:
public class MultiSelectionTreeUI extends BasicTreeUI
{
@Override
protected boolean isToggleSelectionEvent( MouseEvent event )
{
return SwingUtilities.isLeftMouseButton( event );
}
}
And then set that ui on your JTree:
然后在你的JTree上设置ui:
JTree tree = new JTree();
tree.setUI( new MultiSelectionTreeUI() );