/** * Returns whether or not there are more nodes available based on the current configuration of this NodeTreeWalker. * @return True if there are more Nodes available, based on the current configuration, or false otherwise. */ public boolean hasMoreNodes() { if (this.mNextNode == null)//if we've already generated mNextNode { if (this.mCurrentNode == null) this.mNextNode = this.mRootNode.getFirstChild(); else { if (this.mDepthFirst) this.mNextNode = getNextNodeDepthFirst(); else this.mNextNode = getNextNodeBreadthFirst(); } } return (this.mNextNode != null); }
/** * Sets the specified Node as the root Node. * Resets the current position in the tree. * @param rootNode The Node to set as the root of the tree. * @throws NullPointerException if rootNode is null. */ public void setRootNode(Node rootNode) throws NullPointerException { initRootNode(rootNode); }
/** * Traverses to the next Node from the current Node using depth-first tree traversal * @return The next Node from the current Node using depth-first tree traversal. */ protected Node getNextNodeDepthFirst() { //loosely based on http://www.myarch.com/treeiter/traditways.jhtml int currentDepth = getCurrentNodeDepth(); Node traverseNode = null; if ((this.mMaxDepth == -1) || (currentDepth < this.mMaxDepth))//if it is less than max depth, then getting first child won't be more than max depth { traverseNode = this.mCurrentNode.getFirstChild(); if (traverseNode != null) return (traverseNode); } traverseNode = this.mCurrentNode; Node tempNextSibling = null;//keeping a reference to this this saves calling getNextSibling once later while ((traverseNode != this.mRootNode) && (tempNextSibling = traverseNode.getNextSibling()) == null)//CANNOT assign traverseNode as root Node traverseNode = traverseNode.getParent();// use child-parent link to get to the parent level return (tempNextSibling);//null if ran out of Node's }
return (traverseNode); int depth = getCurrentNodeDepth();
/** * Traverses to the next Node from the current Node, using either depth-first or breadth-first tree traversal as appropriate. * @return The next Node from the current Node. */ public Node nextNode() { if (this.mNextNode != null)//check if we've already found the next Node by calling hasMoreNodes() { this.mCurrentNode = this.mNextNode; this.mNextNode = null;//reset mNextNode } else { //Check if we have started traversing yet. If not, start with first child (for either traversal method). if (this.mCurrentNode == null) this.mCurrentNode = this.mRootNode.getFirstChild(); else { if (this.mDepthFirst) this.mCurrentNode = getNextNodeDepthFirst(); else this.mCurrentNode = getNextNodeBreadthFirst(); } } return (this.mCurrentNode); }
/** * Sets the current Node as the root Node. * Resets the current position in the tree. * @throws NullPointerException if the current Node is null (i.e. if the tree traversal has not yet begun). */ public void setCurrentNodeAsRootNode() throws NullPointerException { if (this.mCurrentNode == null) throw new NullPointerException("Current Node is null, cannot set as root Node."); initRootNode(this.mCurrentNode); }
/** * Creates a new instance of NodeTreeWalker using the specified type of tree traversal and maximum depth from the root Node to traverse. * @param rootNode The Node to set as the root of the tree. * @param depthFirst Whether to use depth-first (true) or breadth-first (false) tree traversal. * @param maxDepth The maximum depth from the root Node that this NodeTreeWalker may traverse. This must be > 0 or equal to -1. * @throws NullPointerException if rootNode is null. * @throws IllegalArgumentException maxDepth is not > 0 or equal to -1. */ public NodeTreeWalker(Node rootNode, boolean depthFirst, int maxDepth) { //check maxDepth is valid if ( ! ((maxDepth >= 1) || (maxDepth == -1)))//if not one of these valid possibilities throw new IllegalArgumentException("Paramater maxDepth must be > 0 or equal to -1."); initRootNode(rootNode);//this method also checks if rootNode is valid this.mDepthFirst = depthFirst; this.mMaxDepth = maxDepth; }