package ciips.animation.tree; import java.awt.*; import ciips.animation.*; /** * This class holds the information regarding a node from the heap/complete * binary tree. This class implements the DrawingObj interface * and hence can be freely added to the drawing panel using the * addDrawingObj method. e.g.
 *	TreeNode node = new TreeNode();
 *	drawingPanel.addDrawingObj(node);
 * 
* Any added drawing object can be remove from the panel by using the * removeObj method. e.g.
 *	drawingPanel.removeObj(node);
 * 
* @see DrawingPanel#addDrawingObj * @see DrawingPanel#removeObj */ public class TreeNode implements DrawingObj { protected String label; protected int weight; protected TreeNode left, right; protected int x, y; protected int depth = -1; private boolean red; // Used by red-black trees /** * Attribute to indicate if the left branch is to be highlighted. */ protected boolean highlightLeft = false; /** * Attribute to indicate if the right branch is to be highlighted. */ protected boolean highlightRight = false; /** * Attribute to indicate if the node is to be highlighted. */ public boolean highlight = false; /** * Create a node with the left and right child nodes specified and * the weight of the current node is the sum of the child node. * @param node1 The left node of this newly created node. * @param node2 The right node of this newly created node. */ public TreeNode(TreeNode node1, TreeNode node2) { left = node1; right = node2; weight = node1.getWeight() + node2.getWeight(); // label = new String(); } /** * Create a node with the left node as set and weight of the current node * set to 0. * @param node The left node of the newly created node. */ public TreeNode(TreeNode node) { left = node; right = null; weight = 0; // label = new String(); } /** * Create a new left node with weight 0. */ public TreeNode() { // label = new String(); weight = 0; left = right = null; } // Constructor 1 /** * Create a new leaf node with label and weight as specified in the * parameters. * @param label The label of the new node. * @param weight The weight of the new node. */ public TreeNode(String label, int weight) { this.label = label; this.weight = weight; left = right = null; } // Constructor 2 /** * Create a new leaf node with the specified weight. * @param weight The weight of the new node. */ public TreeNode(int weight) { // this.label = new String(); this.weight = weight; left = right = null; } // Constructor 3 /** * Create a new leaf node with 0 weight and label as specified. * @param label Label of the new node. */ public TreeNode(String label) { this.label = new String(label); this.weight = 0; left = right = null; } // Constructor 4 /** * Set the weight of this node. * @param weight The weight to be assigned to this node. */ public void setWeight(int weight) { this.weight = weight; } /** * Set the label of this node. * @param label The label to be assigned to this node. */ public void setLabel(String label) { this.label = new String(label); } /** * Get the weight of this node. * @return Weight of this node. */ public int getWeight() { return weight; } /** * Get the label of this node. * @return Label of this node. */ public String getLabel() { return new String(label); } /** * Link the left branch of this node to the node passed in as the parameter. * @param node The new left child of this node. */ public void setLeftTreeNode(TreeNode node) { left = node; } /** * Link the right branch of this node to * the node passed in as the parameter. * @param node The new right child of this node. * */ public void setRightTreeNode(TreeNode node) { right = node; } /** * Get the left child of this node. * @return the left child this this node. */ public TreeNode getLeftTreeNode() { return left; } /** * Get the right child of this node. * @return the right child this this node. * */ public TreeNode getRightTreeNode() { return right; } /** * Check if this node is a leaf node. A leaf node has both left and right * nodes null. * @return true if the node is a leaf node; false otherwise. */ public boolean isLeaf() { return ((right==null)&&(left==null)); } /** * Sets the x coordinate of the top-left corner of the node */ public void setX(int x) { this.x = x; } /** * Sets the y coordinate of the top-left corner of the node */ public void setY(int y) { this.y = y; } /** * Get the left most position of the node. * @return The x coordinates of the top-left corner of the node */ public int getX() { return x; } /** * Get the top most position of the node. * @return The y coordinates of the top-left corner of the node */ public int getY() { return y; } /** * Get the depth of his node. * @return The depth of this node in a tree. */ public int getDepth() { return depth; } /** Start at a node and set the positions for the sub-tree elements **/ public void setPosition( int x, int y, int dx, int dy ) { this.x = x; this.y = y; int dx2 = dx/2; if( left != null ) { left.setPosition( x-dx2, y+dy, dx2, dy ); } if( right != null ) { right.setPosition( x+dx2, y+dy, dx2, dy ); } } /** * Sets the depth of this node corresponding to the root node of the tree. * @param depth Depth of the node. */ public void setDepth(int depth) { this.depth = depth; } /** * Move the node and all its branches based on the parameters. * @param x The horizontal destination position of this node. * @param y The vertical destination position of this node. */ public void move(int x, int y) { int dx = x - this.x; int dy = y - this.y; moveTreeNode(dx, dy); } /** * Move the tree starting with node dx pixels to the right and dy * pixels down. * @param node The root node of the tree to be moved. * @param dx The change in x direction. * @param dy The change in y direction. */ public void moveTreeNode(int dx, int dy) { x += dx; y += dy; if (!isLeaf()) { if (getLeftTreeNode() != null) getLeftTreeNode().moveTreeNode(dx, dy); if (getRightTreeNode() != null) getRightTreeNode().moveTreeNode(dx, dy); } } Font hugeFont, bigFont; /** * Assign some font instances to reduce initialization over during * redraw. */ public void initFonts(Font hugeFont, Font bigFont) { this.hugeFont = hugeFont; this.bigFont = bigFont; } protected Color nodeColor = Color.red; protected Color labelColor = Color.yellow; /** * Set the color of the node. * @param nodeColor new color of the node. */ public void initColors(Color nodeColor) { this.nodeColor = nodeColor; } public void setColour( Color x ) { nodeColor = x; } public void setLabelColour( Color x ) { labelColor = x; } /** * This method draws the node on the corresponding graphical context * normally passed in from the drawing panel. */ public void draw(Graphics g) { System.out.println("TreeNode:draw " + getWeight() ); if (highlight) g.setColor(Color.black); else g.setColor( nodeColor ); g.fillRect(x, y, 20, 30); g.setColor(Color.black); g.drawRect(x, y, 20, 30); if ( label != null ) { if (getLabel().length() > 0) { g.setColor( labelColor ); g.setFont( hugeFont ); g.drawString(getLabel(), x + 5, y + 12); } } g.setColor( Color.white ); g.setFont( bigFont ); g.drawString(""+getWeight(), x + 2, y+27); System.out.println("TreeNode:draw " + getWeight() + " exit" ); } } // class TreeNode