From e8540a9c341753a05cc6bac935c48215b1073292 Mon Sep 17 00:00:00 2001 From: Vhati Date: Thu, 28 Nov 2013 23:15:12 -0500 Subject: [PATCH] Added tree recursion stuff --- .../vhati/modmanager/ui/tree/TreeState.java | 148 ++++++++++++++++-- 1 file changed, 135 insertions(+), 13 deletions(-) diff --git a/src/main/java/net/vhati/modmanager/ui/tree/TreeState.java b/src/main/java/net/vhati/modmanager/ui/tree/TreeState.java index 1ea710f..af8cc58 100644 --- a/src/main/java/net/vhati/modmanager/ui/tree/TreeState.java +++ b/src/main/java/net/vhati/modmanager/ui/tree/TreeState.java @@ -1,6 +1,7 @@ package net.vhati.modmanager.ui.tree; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; @@ -10,7 +11,7 @@ import java.util.List; */ public class TreeState { - protected TreeNodeState rootNodeState; + protected TreeNodeState rootNodeState = null; public TreeState() { @@ -26,39 +27,160 @@ public class TreeState { } + public List findNodeStates( TreeNodeStateFilter filter ) { + return findNodeStates( getRootNodeState(), filter ); + } + + /** + * Returns a list of descendant node states which match a given filter. + */ + public List findNodeStates( TreeNodeState currentNodeState, TreeNodeStateFilter filter ) { + List results = new ArrayList( 1 ); + collectNodeStates( currentNodeState, filter, results ); + return results; + } + + public boolean collectNodeStates( TreeNodeState currentNodeState, TreeNodeStateFilter filter, List results ) { + int maxResultCount = filter.getMaxResultCount(); + boolean found = false; + + if ( filter.accept( currentNodeState ) ) { + results.add( currentNodeState ); + if ( maxResultCount > 0 && maxResultCount >= results.size() ) return true; + } + + if ( currentNodeState.getAllowsChildren() ) { + for ( Iterator it = currentNodeState.children(); it.hasNext(); ) { + TreeNodeState childNodeState = it.next(); + found = collectNodeStates( childNodeState, filter, results ); + if ( found && maxResultCount > 0 && maxResultCount >= results.size() ) return true; + } + } + + return found; + } + + + public boolean containsUserObject( Object o ) { + UserObjectTreeNodeStateFilter filter = new UserObjectTreeNodeStateFilter( o ); + filter.setMaxResultCount( 1 ); + List results = findNodeStates( filter ); + + return ( !results.isEmpty() ); + } + + + + public static interface TreeNodeStateFilter { + public int getMaxResultCount(); + public boolean accept( TreeNodeState nodeState ); + } + + + + public static class UserObjectTreeNodeStateFilter implements TreeNodeStateFilter { + + private Class objectClass = null; + private Object o = null; + private int maxResultCount = 0; + + + /** + * Constructs a filter matching objects of a given class (or subclass). + */ + public UserObjectTreeNodeStateFilter( Class objectClass ) { + this.objectClass = objectClass; + } + + /** + * Constructs a filter matching objects equal to a given object. + */ + public UserObjectTreeNodeStateFilter( Object o ) { + this.o = o; + } + + + public void setMaxResultCount( int n ) { maxResultCount = n; } + + @Override + public int getMaxResultCount() { return maxResultCount; } + + @Override + public boolean accept( TreeNodeState nodeState ) { + Object nodeObject = nodeState.getUserObject(); + if ( objectClass != null && nodeObject != null ) { + return ( objectClass.isAssignableFrom( nodeObject.getClass() ) ); + } + else if ( o != null ) { + return ( o.equals( nodeState.getUserObject() ) ); + } + return false; + } + } + public static class TreeNodeState { - + protected Object userObject = null; protected boolean expand = false; protected List children = null; - - + private TreeNodeState parentNodeState = null; + + public TreeNodeState() { this( false, false ); } - + public TreeNodeState( boolean allowsChildren, boolean expand ) { if ( allowsChildren ) { this.expand = expand; children = new ArrayList(); } } - - + + + /** + * Sets this node's parent to newParent but does not change the + * parent's child array. + */ + public void setParent( TreeNodeState nodeState ) { + parentNodeState = nodeState; + } + + public TreeNodeState getParent() { + return parentNodeState; + } + + public boolean getAllowsChildren() { return ( children != null ); } - - public List getChildren() { - return children; + + public void addChild( TreeNodeState childNodeState ) { + TreeNodeState oldParent = childNodeState.getParent(); + if ( oldParent != null ) oldParent.removeChild( childNodeState ); + + childNodeState.setParent( this ); + children.add( childNodeState ); } - - + + public void removeChild( TreeNodeState childNodeState ) { + children.remove( childNodeState ); + childNodeState.setParent( null ); + } + + /** + * Returns an iterator over this node state's children. + */ + public Iterator children() { + return children.iterator(); + } + + public void setUserObject( Object userObject ) { this.userObject = userObject; } - + public Object getUserObject() { return userObject; }