📄 nodetreewalker.java
字号:
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); } /** * Get the number of places down that the current Node is from the root Node. * Returns 1 if current Node is a child of the root Node. * Returns 0 if this NodeTreeWalker has not yet traversed to any Nodes. * @return The depth the current Node is from the root Node. */ public int getCurrentNodeDepth() { int depth = 0; if (this.mCurrentNode != null)//if we are not at the root Node. { Node traverseNode = this.mCurrentNode; while (traverseNode != this.mRootNode) { ++depth; traverseNode = traverseNode.getParent(); } } return (depth); } /** * 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 root Node to be the given 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. */ protected void initRootNode(Node rootNode) throws NullPointerException { if (rootNode == null) throw new NullPointerException("Root Node cannot be null."); this.mRootNode = rootNode; this.mCurrentNode = null; this.mNextNode = null; } /** * 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 } /** * Traverses to the next Node from the current Node using breadth-first tree traversal * @return The next Node from the current Node using breadth-first tree traversal. */ protected Node getNextNodeBreadthFirst() { Node traverseNode; //see if the mCurrentNode has a sibling after it traverseNode = this.mCurrentNode.getNextSibling(); if (traverseNode != null) return (traverseNode); int depth = getCurrentNodeDepth(); //try and find the next Node at the same depth that is not a sibling NodeList traverseNodeList; //step up to the parent Node to look through its children traverseNode = this.mCurrentNode.getParent(); int currentDepth = depth - 1; while(currentDepth > 0)//this is safe as we've tried getNextSibling already { Node tempNextSibling = null;//keeping a reference to this this saves calling getNextSibling once later //go to first parent with nextSibling, then to that sibling while(((tempNextSibling = traverseNode.getNextSibling()) == null) && (traverseNode != this.mRootNode))//CAN assign traverseNode as root Node { traverseNode = traverseNode.getParent(); --currentDepth; } //if have traversed back to the root Node, skip to next part where it finds the first Node at the next depth down if (traverseNode == this.mRootNode) break; traverseNode = tempNextSibling; if (traverseNode != null) { //go through children of that sibling traverseNodeList = traverseNode.getChildren(); while((traverseNodeList != null) && (traverseNodeList.size() != 0)) { traverseNode = traverseNode.getFirstChild(); ++currentDepth; if (currentDepth == depth) return (traverseNode);//found the next Node at the current depth else traverseNodeList = traverseNode.getChildren(); } // while((traverseNodeList != null) && (traverseNodeList.size() != 0)) } // if (traverseNode != null) } // while(currentDepth > 0) //step to the next depth down //check first whether we are about to go past max depth if (this.mMaxDepth != -1)//if -1, then there is no max depth restriction { if (depth >= this.mMaxDepth) return (null);//can't go past max depth } traverseNode = this.mRootNode.getFirstChild(); ++depth;//look for next depth currentDepth = 1; while(currentDepth > 0) { //go through children of that sibling traverseNodeList = traverseNode.getChildren(); while((traverseNodeList != null) && (traverseNodeList.size() != 0)) { traverseNode = traverseNode.getFirstChild(); ++currentDepth; if (currentDepth == depth) return (traverseNode);//found the next Node at the current depth else traverseNodeList = traverseNode.getChildren(); } // while((traverseNodeList != null) && (traverseNodeList.size() != 0)) //go to first parent with nextSibling, then to that sibling while((traverseNode.getNextSibling() == null) && (traverseNode != this.mRootNode)) { traverseNode = traverseNode.getParent(); --currentDepth; } traverseNode = traverseNode.getNextSibling(); if (traverseNode == null)//if null (i.e. reached end of tree), return null return (null); } // while(currentDepth > 0) //otherwise, finished searching, return null return (null); } // todo // previousNode() // getPreviousNodeDepthFirst() // getPreviousNodeBreadthFirst() // hasPreviousNodes() ? // these should be specificed in an interface - suggest something like ReversableNodeIterator (extends NodeIterator) // possible optimisations: when doing mNextNode, we should save mCurrentNode as previousNode, and vice versa}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -