Exemplo n.º 1
0
  /**
   * Returns the nearest common ancestor to this node and <code>aNode</code>. Returns null, if no
   * such ancestor exists -- if this node and <code>aNode</code> are in different trees or if <code>
   * aNode</code> is null. A node is considered an ancestor of itself.
   *
   * @see #isNodeAncestor
   * @see #isNodeDescendant
   * @param aNode node to find common ancestor with
   * @return nearest ancestor common to this node and <code>aNode</code>, or null if none
   */
  public TreeNode getSharedAncestor(DefaultMutableTreeNode aNode) {
    if (aNode == this) {
      return this;
    } else if (aNode == null) {
      return null;
    }

    int level1, level2, diff;
    TreeNode node1, node2;

    level1 = getLevel();
    level2 = aNode.getLevel();

    if (level2 > level1) {
      diff = level2 - level1;
      node1 = aNode;
      node2 = this;
    } else {
      diff = level1 - level2;
      node1 = this;
      node2 = aNode;
    }

    // Go up the tree until the nodes are at the same level
    while (diff > 0) {
      node1 = node1.getParent();
      diff--;
    }

    // Move up the tree until we find a common ancestor.  Since we know
    // that both nodes are at the same level, we won't cross paths
    // unknowingly (if there is a common ancestor, both nodes hit it in
    // the same iteration).

    do {
      if (node1 == node2) {
        return node1;
      }
      node1 = node1.getParent();
      node2 = node2.getParent();
    } while (node1 != null); // only need to check one -- they're at the
    // same level so if one is null, the other is

    if (node1 != null || node2 != null) {
      throw new Error("nodes should be null");
    }

    return null;
  }
Exemplo n.º 2
0
  /**
   * Returns the root of the tree that contains this node. The root is the ancestor with a null
   * parent.
   *
   * @see #isNodeAncestor
   * @return the root of the tree that contains this node
   */
  public TreeNode getRoot() {
    TreeNode ancestor = this;
    TreeNode previous;

    do {
      previous = ancestor;
      ancestor = ancestor.getParent();
    } while (ancestor != null);

    return previous;
  }
Exemplo n.º 3
0
  /**
   * Returns the number of levels above this node -- the distance from the root to this node. If
   * this node is the root, returns 0.
   *
   * @see #getDepth
   * @return the number of levels above this node
   */
  public int getLevel() {
    TreeNode ancestor;
    int levels = 0;

    ancestor = this;
    while ((ancestor = ancestor.getParent()) != null) {
      levels++;
    }

    return levels;
  }
Exemplo n.º 4
0
  /**
   * Returns true if <code>aNode</code> is a child of this node. If <code>aNode</code> is null, this
   * method returns false.
   *
   * @return true if <code>aNode</code> is a child of this node; false if <code>aNode</code> is null
   */
  public boolean isNodeChild(TreeNode aNode) {
    boolean retval;

    if (aNode == null) {
      retval = false;
    } else {
      if (getChildCount() == 0) {
        retval = false;
      } else {
        retval = (aNode.getParent() == this);
      }
    }

    return retval;
  }
Exemplo n.º 5
0
  /**
   * Builds the parents of node up to and including the root node, where the original node is the
   * last element in the returned array. The length of the returned array gives the node's depth in
   * the tree.
   *
   * @param aNode the TreeNode to get the path for
   * @param depth an int giving the number of steps already taken towards the root (on recursive
   *     calls), used to size the returned array
   * @return an array of TreeNodes giving the path from the root to the specified node
   */
  protected TreeNode[] getPathToRoot(TreeNode aNode, int depth) {
    TreeNode[] retNodes;

    /* Check for null, in case someone passed in a null node, or
    they passed in an element that isn't rooted at root. */
    if (aNode == null) {
      if (depth == 0) return null;
      else retNodes = new TreeNode[depth];
    } else {
      depth++;
      retNodes = getPathToRoot(aNode.getParent(), depth);
      retNodes[retNodes.length - depth] = aNode;
    }
    return retNodes;
  }
Exemplo n.º 6
0
  /**
   * Returns true if <code>anotherNode</code> is an ancestor of this node -- if it is this node,
   * this node's parent, or an ancestor of this node's parent. (Note that a node is considered an
   * ancestor of itself.) If <code>anotherNode</code> is null, this method returns false. This
   * operation is at worst O(h) where h is the distance from the root to this node.
   *
   * @see #isNodeDescendant
   * @see #getSharedAncestor
   * @param anotherNode node to test as an ancestor of this node
   * @return true if this node is a descendant of <code>anotherNode</code>
   */
  public boolean isNodeAncestor(TreeNode anotherNode) {
    if (anotherNode == null) {
      return false;
    }

    TreeNode ancestor = this;

    do {
      if (ancestor == anotherNode) {
        return true;
      }
    } while ((ancestor = ancestor.getParent()) != null);

    return false;
  }
Exemplo n.º 7
0
  /**
   * Returns true if <code>anotherNode</code> is a sibling of (has the same parent as) this node. A
   * node is its own sibling. If <code>anotherNode</code> is null, returns false.
   *
   * @param anotherNode node to test as sibling of this node
   * @return true if <code>anotherNode</code> is a sibling of this node
   */
  public boolean isNodeSibling(TreeNode anotherNode) {
    boolean retval;

    if (anotherNode == null) {
      retval = false;
    } else if (anotherNode == this) {
      retval = true;
    } else {
      TreeNode myParent = getParent();
      retval = (myParent != null && myParent == anotherNode.getParent());

      if (retval && !((DefaultMutableTreeNode) getParent()).isNodeChild(anotherNode)) {
        throw new Error("sibling has different parent");
      }
    }

    return retval;
  }
Exemplo n.º 8
0
    public PathBetweenNodesEnumeration(TreeNode ancestor, TreeNode descendant) {
      super();

      if (ancestor == null || descendant == null) {
        throw new IllegalArgumentException("argument is null");
      }

      TreeNode current;

      stack = new Stack<TreeNode>();
      stack.push(descendant);

      current = descendant;
      while (current != ancestor) {
        current = current.getParent();
        if (current == null && descendant != ancestor) {
          throw new IllegalArgumentException(
              "node " + ancestor + " is not an ancestor of " + descendant);
        }
        stack.push(current);
      }
    }