Added tree UI classes (not used yet)
This commit is contained in:
parent
6ca3fad77b
commit
71aabb6205
12 changed files with 1377 additions and 0 deletions
|
|
@ -0,0 +1,258 @@
|
|||
/*
|
||||
* Based on CheckTreeSelectionModel (rev 120, 2007-07-20)
|
||||
* By Santhosh Kumar T
|
||||
* https://java.net/projects/myswing
|
||||
*
|
||||
* https://java.net/projects/myswing/sources/svn/content/trunk/src/skt/swing/tree/check/CheckTreeSelectionModel.java?rev=120
|
||||
*/
|
||||
|
||||
/**
|
||||
* MySwing: Advanced Swing Utilites
|
||||
* Copyright (C) 2005 Santhosh Kumar T
|
||||
* <p/>
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
* <p/>
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*/
|
||||
|
||||
package net.vhati.modmanager.ui.tree;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Stack;
|
||||
import javax.swing.tree.DefaultTreeSelectionModel;
|
||||
import javax.swing.tree.TreeModel;
|
||||
import javax.swing.tree.TreePath;
|
||||
import javax.swing.tree.TreeSelectionModel;
|
||||
|
||||
import net.vhati.modmanager.ui.tree.PreorderEnumeration;
|
||||
|
||||
|
||||
public class ChecklistTreeSelectionModel extends DefaultTreeSelectionModel {
|
||||
|
||||
private TreeModel model;
|
||||
private boolean dig = true;
|
||||
|
||||
|
||||
public ChecklistTreeSelectionModel( TreeModel model, boolean dig ) {
|
||||
this.model = model;
|
||||
this.dig = dig;
|
||||
this.setSelectionMode( TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION );
|
||||
}
|
||||
|
||||
public boolean isDigged() {
|
||||
return dig;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if path1 is a descendant of path2.
|
||||
*/
|
||||
private boolean isDescendant( TreePath path1, TreePath path2 ) {
|
||||
Object obj1[] = path1.getPath();
|
||||
Object obj2[] = path2.getPath();
|
||||
for ( int i=0; i < obj2.length; i++ ) {
|
||||
if ( obj1[i] != obj2[i] ) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true a selected node exists in the subtree of a given unselected path.
|
||||
* Returns false if the given path is itself selected.
|
||||
*/
|
||||
public boolean isPartiallySelected( TreePath path ) {
|
||||
if ( isPathSelected( path, true ) ) return false;
|
||||
|
||||
TreePath[] selectionPaths = getSelectionPaths();
|
||||
if( selectionPaths == null ) return false;
|
||||
|
||||
for ( int j=0; j < selectionPaths.length; j++ ) {
|
||||
if ( isDescendant( selectionPaths[j], path ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if a given path is selected.
|
||||
*
|
||||
* If dig is true, then the path is assumed to be selected, if
|
||||
* one of its ancestors is selected.
|
||||
*/
|
||||
public boolean isPathSelected( TreePath path, boolean dig ) {
|
||||
if ( !dig ) return super.isPathSelected( path );
|
||||
|
||||
while ( path != null && !super.isPathSelected( path ) ) {
|
||||
path = path.getParentPath();
|
||||
}
|
||||
return ( path != null );
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setSelectionPaths( TreePath[] paths ) {
|
||||
if ( dig ) {
|
||||
throw new UnsupportedOperationException();
|
||||
} else {
|
||||
super.setSelectionPaths( paths );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addSelectionPaths( TreePath[] paths ) {
|
||||
if ( !dig ) {
|
||||
super.addSelectionPaths( paths );
|
||||
return;
|
||||
}
|
||||
|
||||
// Unselect all descendants of paths[].
|
||||
for( int i=0; i < paths.length; i++ ) {
|
||||
TreePath path = paths[i];
|
||||
TreePath[] selectionPaths = getSelectionPaths();
|
||||
if ( selectionPaths == null ) break;
|
||||
|
||||
ArrayList toBeRemoved = new ArrayList();
|
||||
for ( int j=0; j < selectionPaths.length; j++ ) {
|
||||
if ( isDescendant( selectionPaths[j], path ) ) {
|
||||
toBeRemoved.add( selectionPaths[j] );
|
||||
}
|
||||
}
|
||||
super.removeSelectionPaths( (TreePath[])toBeRemoved.toArray( new TreePath[0] ) );
|
||||
}
|
||||
|
||||
// If all siblings are selected then unselect them and select parent recursively
|
||||
// otherwize just select that path.
|
||||
for ( int i=0; i < paths.length; i++ ) {
|
||||
TreePath path = paths[i];
|
||||
TreePath temp = null;
|
||||
while ( areSiblingsSelected(path) ) {
|
||||
temp = path;
|
||||
if ( path.getParentPath() == null ) break;
|
||||
path = path.getParentPath();
|
||||
}
|
||||
if ( temp != null ) {
|
||||
if ( temp.getParentPath() != null ) {
|
||||
addSelectionPath( temp.getParentPath() );
|
||||
}
|
||||
else {
|
||||
if ( !isSelectionEmpty() ) {
|
||||
removeSelectionPaths(getSelectionPaths());
|
||||
}
|
||||
super.addSelectionPaths( new TreePath[]{temp} );
|
||||
}
|
||||
}
|
||||
else {
|
||||
super.addSelectionPaths( new TreePath[]{path} );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeSelectionPaths( TreePath[] paths ) {
|
||||
if( !dig ) {
|
||||
super.removeSelectionPaths( paths );
|
||||
return;
|
||||
}
|
||||
|
||||
for ( int i=0; i < paths.length; i++ ) {
|
||||
TreePath path = paths[i];
|
||||
if ( path.getPathCount() == 1 ) {
|
||||
super.removeSelectionPaths( new TreePath[]{path} );
|
||||
} else {
|
||||
toggleRemoveSelection(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if all siblings of given path are selected.
|
||||
*/
|
||||
private boolean areSiblingsSelected( TreePath path ) {
|
||||
TreePath parent = path.getParentPath();
|
||||
if ( parent == null ) return true;
|
||||
|
||||
Object node = path.getLastPathComponent();
|
||||
Object parentNode = parent.getLastPathComponent();
|
||||
|
||||
int childCount = model.getChildCount( parentNode );
|
||||
for ( int i=0; i < childCount; i++ ) {
|
||||
Object childNode = model.getChild( parentNode, i );
|
||||
if ( childNode == node ) continue;
|
||||
|
||||
if ( !isPathSelected( parent.pathByAddingChild( childNode ) ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Unselects a given path, toggling ancestors if they were entirely selected.
|
||||
*
|
||||
* If any ancestor node of the given path is selected, it will be unselected,
|
||||
* and all its descendants - except any within the given path - will be selected.
|
||||
* The ancestor will have gone from fully selected to partially selected.
|
||||
*
|
||||
* Otherwise, the given path will be unselected, and nothing else will change.
|
||||
*/
|
||||
private void toggleRemoveSelection( TreePath path ) {
|
||||
Stack stack = new Stack();
|
||||
TreePath parent = path.getParentPath();
|
||||
|
||||
while ( parent != null && !isPathSelected( parent ) ) {
|
||||
stack.push( parent );
|
||||
parent = parent.getParentPath();
|
||||
}
|
||||
|
||||
if ( parent != null ) {
|
||||
stack.push( parent );
|
||||
}
|
||||
else {
|
||||
super.removeSelectionPaths( new TreePath[]{path} );
|
||||
return;
|
||||
}
|
||||
|
||||
while ( !stack.isEmpty() ) {
|
||||
TreePath temp = (TreePath)stack.pop();
|
||||
TreePath peekPath = ( stack.isEmpty() ? path : (TreePath)stack.peek() );
|
||||
Object node = temp.getLastPathComponent();
|
||||
Object peekNode = peekPath.getLastPathComponent();
|
||||
|
||||
int childCount = model.getChildCount( node );
|
||||
for ( int i=0; i < childCount; i++ ) {
|
||||
Object childNode = model.getChild( node, i );
|
||||
if ( childNode != peekNode ) {
|
||||
super.addSelectionPaths( new TreePath[]{temp.pathByAddingChild( childNode )} );
|
||||
}
|
||||
}
|
||||
}
|
||||
super.removeSelectionPaths( new TreePath[]{parent} );
|
||||
}
|
||||
|
||||
|
||||
public Enumeration getAllSelectedPaths() {
|
||||
TreePath[] treePaths = getSelectionPaths();
|
||||
if ( treePaths == null ) {
|
||||
return Collections.enumeration( Collections.EMPTY_LIST );
|
||||
}
|
||||
|
||||
Enumeration enumer = Collections.enumeration( Arrays.asList( treePaths ) );
|
||||
if ( dig ) {
|
||||
enumer = new PreorderEnumeration( enumer, model );
|
||||
}
|
||||
return enumer;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue