home *** CD-ROM | disk | FTP | other *** search
/ Symantec Visual Cafe for Java 2.5 / symantec-visual-cafe-2.5-database-dev-edition.iso / VCafe / debug / databind.jar / javax / awt / swing / tree / DefaultMutableTreeNode.class (.txt) next >
Encoding:
Java Class File  |  1998-03-19  |  12.0 KB  |  541 lines

  1. package javax.awt.swing.tree;
  2.  
  3. import java.io.IOException;
  4. import java.io.ObjectInputStream;
  5. import java.io.ObjectOutputStream;
  6. import java.io.Serializable;
  7. import java.util.Enumeration;
  8. import java.util.NoSuchElementException;
  9. import java.util.Vector;
  10.  
  11. public class DefaultMutableTreeNode implements Cloneable, MutableTreeNode, Serializable {
  12.    public static final Enumeration EMPTY_ENUMERATION = new 1();
  13.    protected MutableTreeNode parent;
  14.    protected Vector children;
  15.    protected transient Object userObject;
  16.    protected boolean allowsChildren;
  17.  
  18.    public DefaultMutableTreeNode() {
  19.       this((Object)null);
  20.    }
  21.  
  22.    public DefaultMutableTreeNode(Object userObject) {
  23.       this(userObject, true);
  24.    }
  25.  
  26.    public DefaultMutableTreeNode(Object userObject, boolean allowsChildren) {
  27.       this.parent = null;
  28.       this.allowsChildren = allowsChildren;
  29.       this.userObject = userObject;
  30.    }
  31.  
  32.    public void insert(MutableTreeNode newChild, int childIndex) {
  33.       if (!this.allowsChildren) {
  34.          throw new IllegalStateException("node does not allow children");
  35.       } else if (newChild == null) {
  36.          throw new IllegalArgumentException("new child is null");
  37.       } else if (this.isNodeAncestor(newChild)) {
  38.          throw new IllegalArgumentException("new child is an ancestor");
  39.       } else {
  40.          MutableTreeNode oldParent = (MutableTreeNode)newChild.getParent();
  41.          if (oldParent != null) {
  42.             oldParent.remove(newChild);
  43.          }
  44.  
  45.          newChild.setParent(this);
  46.          if (this.children == null) {
  47.             this.children = new Vector();
  48.          }
  49.  
  50.          this.children.insertElementAt(newChild, childIndex);
  51.       }
  52.    }
  53.  
  54.    public void remove(int childIndex) {
  55.       MutableTreeNode child = (MutableTreeNode)this.getChildAt(childIndex);
  56.       this.children.removeElementAt(childIndex);
  57.       child.setParent((MutableTreeNode)null);
  58.    }
  59.  
  60.    public void setParent(MutableTreeNode newParent) {
  61.       this.parent = newParent;
  62.    }
  63.  
  64.    public TreeNode getParent() {
  65.       return this.parent;
  66.    }
  67.  
  68.    public TreeNode getChildAt(int index) {
  69.       if (this.children == null) {
  70.          throw new ArrayIndexOutOfBoundsException("node has no children");
  71.       } else {
  72.          return (TreeNode)this.children.elementAt(index);
  73.       }
  74.    }
  75.  
  76.    public int getChildCount() {
  77.       return this.children == null ? 0 : this.children.size();
  78.    }
  79.  
  80.    public int getIndex(TreeNode aChild) {
  81.       if (aChild == null) {
  82.          throw new IllegalArgumentException("argument is null");
  83.       } else {
  84.          return !this.isNodeChild(aChild) ? -1 : this.children.indexOf(aChild);
  85.       }
  86.    }
  87.  
  88.    public Enumeration children() {
  89.       return this.children == null ? EMPTY_ENUMERATION : this.children.elements();
  90.    }
  91.  
  92.    public void setAllowsChildren(boolean allows) {
  93.       if (allows != this.allowsChildren) {
  94.          this.allowsChildren = allows;
  95.          if (!this.allowsChildren) {
  96.             this.removeAllChildren();
  97.          }
  98.       }
  99.  
  100.    }
  101.  
  102.    public boolean getAllowsChildren() {
  103.       return this.allowsChildren;
  104.    }
  105.  
  106.    public void setUserObject(Object userObject) {
  107.       this.userObject = userObject;
  108.    }
  109.  
  110.    public Object getUserObject() {
  111.       return this.userObject;
  112.    }
  113.  
  114.    public void removeFromParent() {
  115.       MutableTreeNode parent = (MutableTreeNode)this.getParent();
  116.       if (parent != null) {
  117.          parent.remove(this);
  118.       }
  119.  
  120.    }
  121.  
  122.    public void remove(MutableTreeNode aChild) {
  123.       if (aChild == null) {
  124.          throw new IllegalArgumentException("argument is null");
  125.       } else if (!this.isNodeChild(aChild)) {
  126.          throw new IllegalArgumentException("argument is not a child");
  127.       } else {
  128.          this.remove(this.getIndex(aChild));
  129.       }
  130.    }
  131.  
  132.    public void removeAllChildren() {
  133.       for(int i = this.getChildCount() - 1; i >= 0; --i) {
  134.          this.remove(i);
  135.       }
  136.  
  137.    }
  138.  
  139.    public void add(MutableTreeNode newChild) {
  140.       if (newChild != null && newChild.getParent() == this) {
  141.          this.insert(newChild, this.getChildCount() - 1);
  142.       } else {
  143.          this.insert(newChild, this.getChildCount());
  144.       }
  145.  
  146.    }
  147.  
  148.    public boolean isNodeAncestor(TreeNode anotherNode) {
  149.       if (anotherNode == null) {
  150.          return false;
  151.       } else {
  152.          TreeNode ancestor = this;
  153.  
  154.          while(ancestor != anotherNode) {
  155.             if ((ancestor = ancestor.getParent()) == null) {
  156.                return false;
  157.             }
  158.          }
  159.  
  160.          return true;
  161.       }
  162.    }
  163.  
  164.    public boolean isNodeDescendant(DefaultMutableTreeNode anotherNode) {
  165.       return anotherNode == null ? false : anotherNode.isNodeAncestor(this);
  166.    }
  167.  
  168.    public TreeNode getSharedAncestor(DefaultMutableTreeNode aNode) {
  169.       if (aNode == this) {
  170.          return this;
  171.       } else if (aNode == null) {
  172.          return null;
  173.       } else {
  174.          int level1 = this.getLevel();
  175.          int level2 = aNode.getLevel();
  176.          int diff;
  177.          TreeNode node1;
  178.          TreeNode node2;
  179.          if (level2 > level1) {
  180.             diff = level2 - level1;
  181.             node1 = aNode;
  182.             node2 = this;
  183.          } else {
  184.             diff = level1 - level2;
  185.             node1 = this;
  186.             node2 = aNode;
  187.          }
  188.  
  189.          while(diff > 0) {
  190.             node1 = node1.getParent();
  191.             --diff;
  192.          }
  193.  
  194.          while(node1 != node2) {
  195.             node1 = node1.getParent();
  196.             node2 = node2.getParent();
  197.             if (node1 == null) {
  198.                if (node1 == null && node2 == null) {
  199.                   return null;
  200.                }
  201.  
  202.                throw new InternalError("nodes should be null");
  203.             }
  204.          }
  205.  
  206.          return node1;
  207.       }
  208.    }
  209.  
  210.    public boolean isNodeRelated(DefaultMutableTreeNode aNode) {
  211.       return aNode != null && this.getRoot() == aNode.getRoot();
  212.    }
  213.  
  214.    public int getDepth() {
  215.       Object last = null;
  216.  
  217.       for(Enumeration enum = this.breadthFirstEnumeration(); enum.hasMoreElements(); last = enum.nextElement()) {
  218.       }
  219.  
  220.       if (last == null) {
  221.          throw new InternalError("nodes should be null");
  222.       } else {
  223.          return ((DefaultMutableTreeNode)last).getLevel() - this.getLevel();
  224.       }
  225.    }
  226.  
  227.    public int getLevel() {
  228.       int levels = 0;
  229.  
  230.       for(TreeNode ancestor = this; (ancestor = ancestor.getParent()) != null; ++levels) {
  231.       }
  232.  
  233.       return levels;
  234.    }
  235.  
  236.    public TreeNode[] getPath() {
  237.       return this.getPathToRoot(this, 0);
  238.    }
  239.  
  240.    protected TreeNode[] getPathToRoot(TreeNode aNode, int depth) {
  241.       TreeNode[] retNodes;
  242.       if (aNode == null) {
  243.          if (depth == 0) {
  244.             return null;
  245.          }
  246.  
  247.          retNodes = new TreeNode[depth];
  248.       } else {
  249.          ++depth;
  250.          retNodes = this.getPathToRoot(aNode.getParent(), depth);
  251.          retNodes[retNodes.length - depth] = aNode;
  252.       }
  253.  
  254.       return retNodes;
  255.    }
  256.  
  257.    public Object[] getUserObjectPath() {
  258.       TreeNode[] realPath = this.getPath();
  259.       Object[] retPath = new Object[realPath.length];
  260.  
  261.       for(int counter = 0; counter < realPath.length; ++counter) {
  262.          retPath[counter] = ((DefaultMutableTreeNode)realPath[counter]).getUserObject();
  263.       }
  264.  
  265.       return retPath;
  266.    }
  267.  
  268.    public TreeNode getRoot() {
  269.       TreeNode ancestor = this;
  270.  
  271.       TreeNode previous;
  272.       do {
  273.          previous = ancestor;
  274.          ancestor = ancestor.getParent();
  275.       } while(ancestor != null);
  276.  
  277.       return previous;
  278.    }
  279.  
  280.    public boolean isRoot() {
  281.       return this.getParent() == null;
  282.    }
  283.  
  284.    public DefaultMutableTreeNode getNextNode() {
  285.       if (this.getChildCount() != 0) {
  286.          return (DefaultMutableTreeNode)this.getChildAt(0);
  287.       } else {
  288.          DefaultMutableTreeNode nextSibling = this.getNextSibling();
  289.          if (nextSibling != null) {
  290.             return nextSibling;
  291.          } else {
  292.             for(DefaultMutableTreeNode aNode = (DefaultMutableTreeNode)this.getParent(); aNode != null; aNode = (DefaultMutableTreeNode)aNode.getParent()) {
  293.                nextSibling = aNode.getNextSibling();
  294.                if (nextSibling != null) {
  295.                   return nextSibling;
  296.                }
  297.             }
  298.  
  299.             return null;
  300.          }
  301.       }
  302.    }
  303.  
  304.    public DefaultMutableTreeNode getPreviousNode() {
  305.       DefaultMutableTreeNode myParent = (DefaultMutableTreeNode)this.getParent();
  306.       if (myParent == null) {
  307.          return null;
  308.       } else {
  309.          DefaultMutableTreeNode previousSibling = this.getPreviousSibling();
  310.          return previousSibling != null ? (previousSibling.getChildCount() == 0 ? previousSibling : previousSibling.getLastLeaf()) : myParent;
  311.       }
  312.    }
  313.  
  314.    public Enumeration preorderEnumeration() {
  315.       return new PreorderEnumeration(this, this);
  316.    }
  317.  
  318.    public Enumeration postorderEnumeration() {
  319.       return new PostorderEnumeration(this, this);
  320.    }
  321.  
  322.    public Enumeration breadthFirstEnumeration() {
  323.       return new BreadthFirstEnumeration(this, this);
  324.    }
  325.  
  326.    public Enumeration depthFirstEnumeration() {
  327.       return this.postorderEnumeration();
  328.    }
  329.  
  330.    public Enumeration pathFromAncestorEnumeration(TreeNode ancestor) {
  331.       return new PathBetweenNodesEnumeration(this, ancestor, this);
  332.    }
  333.  
  334.    public boolean isNodeChild(TreeNode aNode) {
  335.       boolean retval;
  336.       if (aNode == null) {
  337.          retval = false;
  338.       } else if (this.getChildCount() == 0) {
  339.          retval = false;
  340.       } else {
  341.          retval = aNode.getParent() == this;
  342.       }
  343.  
  344.       return retval;
  345.    }
  346.  
  347.    public TreeNode getFirstChild() {
  348.       if (this.getChildCount() == 0) {
  349.          throw new NoSuchElementException("node has no children");
  350.       } else {
  351.          return this.getChildAt(0);
  352.       }
  353.    }
  354.  
  355.    public TreeNode getLastChild() {
  356.       if (this.getChildCount() == 0) {
  357.          throw new NoSuchElementException("node has no children");
  358.       } else {
  359.          return this.getChildAt(this.getChildCount() - 1);
  360.       }
  361.    }
  362.  
  363.    public TreeNode getChildAfter(TreeNode aChild) {
  364.       if (aChild == null) {
  365.          throw new IllegalArgumentException("argument is null");
  366.       } else {
  367.          int index = this.getIndex(aChild);
  368.          if (index == -1) {
  369.             throw new IllegalArgumentException("node is not a child");
  370.          } else {
  371.             return index < this.getChildCount() - 1 ? this.getChildAt(index + 1) : null;
  372.          }
  373.       }
  374.    }
  375.  
  376.    public TreeNode getChildBefore(TreeNode aChild) {
  377.       if (aChild == null) {
  378.          throw new IllegalArgumentException("argument is null");
  379.       } else {
  380.          int index = this.getIndex(aChild);
  381.          if (index == -1) {
  382.             throw new IllegalArgumentException("argument is not a child");
  383.          } else {
  384.             return index > 0 ? this.getChildAt(index - 1) : null;
  385.          }
  386.       }
  387.    }
  388.  
  389.    public boolean isNodeSibling(TreeNode anotherNode) {
  390.       boolean retval;
  391.       if (anotherNode == null) {
  392.          retval = false;
  393.       } else if (anotherNode == this) {
  394.          retval = true;
  395.       } else {
  396.          TreeNode myParent = this.getParent();
  397.          retval = myParent != null && myParent == anotherNode.getParent();
  398.          if (retval && !((DefaultMutableTreeNode)this.getParent()).isNodeChild(anotherNode)) {
  399.             throw new InternalError("sibling has different parent");
  400.          }
  401.       }
  402.  
  403.       return retval;
  404.    }
  405.  
  406.    public int getSiblingCount() {
  407.       TreeNode myParent = this.getParent();
  408.       return myParent == null ? 1 : myParent.getChildCount();
  409.    }
  410.  
  411.    public DefaultMutableTreeNode getNextSibling() {
  412.       DefaultMutableTreeNode myParent = (DefaultMutableTreeNode)this.getParent();
  413.       DefaultMutableTreeNode retval;
  414.       if (myParent == null) {
  415.          retval = null;
  416.       } else {
  417.          retval = (DefaultMutableTreeNode)myParent.getChildAfter(this);
  418.       }
  419.  
  420.       if (retval != null && !this.isNodeSibling(retval)) {
  421.          throw new InternalError("child of parent is not a sibling");
  422.       } else {
  423.          return retval;
  424.       }
  425.    }
  426.  
  427.    public DefaultMutableTreeNode getPreviousSibling() {
  428.       DefaultMutableTreeNode myParent = (DefaultMutableTreeNode)this.getParent();
  429.       DefaultMutableTreeNode retval;
  430.       if (myParent == null) {
  431.          retval = null;
  432.       } else {
  433.          retval = (DefaultMutableTreeNode)myParent.getChildBefore(this);
  434.       }
  435.  
  436.       if (retval != null && !this.isNodeSibling(retval)) {
  437.          throw new InternalError("child of parent is not a sibling");
  438.       } else {
  439.          return retval;
  440.       }
  441.    }
  442.  
  443.    public boolean isLeaf() {
  444.       return this.getChildCount() == 0;
  445.    }
  446.  
  447.    public DefaultMutableTreeNode getFirstLeaf() {
  448.       DefaultMutableTreeNode node;
  449.       for(node = this; !node.isLeaf(); node = (DefaultMutableTreeNode)node.getFirstChild()) {
  450.       }
  451.  
  452.       return node;
  453.    }
  454.  
  455.    public DefaultMutableTreeNode getLastLeaf() {
  456.       DefaultMutableTreeNode node;
  457.       for(node = this; !node.isLeaf(); node = (DefaultMutableTreeNode)node.getLastChild()) {
  458.       }
  459.  
  460.       return node;
  461.    }
  462.  
  463.    public DefaultMutableTreeNode getNextLeaf() {
  464.       DefaultMutableTreeNode myParent = (DefaultMutableTreeNode)this.getParent();
  465.       if (myParent == null) {
  466.          return null;
  467.       } else {
  468.          DefaultMutableTreeNode nextSibling = this.getNextSibling();
  469.          return nextSibling != null ? nextSibling.getFirstLeaf() : myParent.getNextLeaf();
  470.       }
  471.    }
  472.  
  473.    public DefaultMutableTreeNode getPreviousLeaf() {
  474.       DefaultMutableTreeNode myParent = (DefaultMutableTreeNode)this.getParent();
  475.       if (myParent == null) {
  476.          return null;
  477.       } else {
  478.          DefaultMutableTreeNode previousSibling = this.getPreviousSibling();
  479.          return previousSibling != null ? previousSibling.getLastLeaf() : myParent.getPreviousLeaf();
  480.       }
  481.    }
  482.  
  483.    public int getLeafCount() {
  484.       int count = 0;
  485.       Enumeration enum = this.breadthFirstEnumeration();
  486.  
  487.       while(enum.hasMoreElements()) {
  488.          TreeNode node = (TreeNode)enum.nextElement();
  489.          if (node.isLeaf()) {
  490.             ++count;
  491.          }
  492.       }
  493.  
  494.       if (count < 1) {
  495.          throw new InternalError("tree has zero leaves");
  496.       } else {
  497.          return count;
  498.       }
  499.    }
  500.  
  501.    public String toString() {
  502.       return this.userObject == null ? null : this.userObject.toString();
  503.    }
  504.  
  505.    public Object clone() {
  506.       DefaultMutableTreeNode newNode = null;
  507.  
  508.       try {
  509.          newNode = (DefaultMutableTreeNode)super.clone();
  510.          newNode.children = null;
  511.          newNode.parent = null;
  512.          return newNode;
  513.       } catch (CloneNotSupportedException e) {
  514.          throw new InternalError(((Throwable)e).toString());
  515.       }
  516.    }
  517.  
  518.    private void writeObject(ObjectOutputStream s) throws IOException {
  519.       s.defaultWriteObject();
  520.       Object[] tValues;
  521.       if (this.userObject != null && this.userObject instanceof Serializable) {
  522.          tValues = new Object[2];
  523.          tValues[0] = "userObject";
  524.          tValues[1] = this.userObject;
  525.       } else {
  526.          tValues = new Object[0];
  527.       }
  528.  
  529.       s.writeObject(tValues);
  530.    }
  531.  
  532.    private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
  533.       s.defaultReadObject();
  534.       Object[] tValues = s.readObject();
  535.       if (tValues.length > 0 && tValues[0].equals("userObject")) {
  536.          this.userObject = tValues[1];
  537.       }
  538.  
  539.    }
  540. }
  541.