import java.awt.*;
import java.util.*;
/**
* The BinTree
class provides the utilities to draw a complete
* binary tree on the corresponding graphical context. It also contains
* some animation methods used in heap sort, priority queue
* and sorting using priority queue
*
* There are basically 4 types of graphical objects: input,
* output, tree representation of heap, and
* array representation of heap.
* The Node
class is used to store the graphical objects.
* @see Node
*/
public class BinTree implements DrawingObj {
Font bigFont, smallFont, tinyFont, hugeFont, fixFont;
DrawingPanel drawingPanel;
OBSAnim obsAnim;
Node tree, posn;
Vector nodeList, posnList;
int max_node_per_level, depth;
Node movingNode;
Point[] aPoints;
Color darkgreen = new Color(0, 140, 0);
Color darkRed = new Color(140, 0, 0);
Color darkBlue = new Color(0, 0, 140);
int max_size;
int tmp1X, tmp1Y, tmp2X, tmp2Y, tmp3X, tmp3Y;
String tmp1Str = new String(), tmp2Str = new String(),
tmp3Str = new String();
static final int horizSpace = 32, vertSpace = 17;
/**
* Create a new heap and pre-calculate the location of each node
* given the maximum number of node passed in as the parameter.
* @param drawingPanel The drawing panel where the heap is to be drawn.
* @param max_size The maximum number of nodes in the heap.
*/
public BinTree(OBSAnim obsAnim, DrawingPanel drawingPanel, int max_size) {
this.obsAnim = obsAnim;
this.bigFont = drawingPanel.getBigFont();
this.smallFont = drawingPanel.getSmallFont();
this.tinyFont = drawingPanel.getTinyFont();
this.hugeFont = drawingPanel.getHugeFont();
this.fixFont = drawingPanel.getFixFont();
this.drawingPanel = drawingPanel;
this.max_size = max_size;
this.tree = null;
nodeList = new Vector();
posnList = new Vector();
calNodesCoord(max_size);
hideMovingNode();
}
/**
* Repaints the drawing panel and delay.
*/
public void redraw() {
drawingPanel.repaint();
drawingPanel.delay();
}
/**
* Re-initialize the heap. This method is called when the animation
* is re-started.
*/
public void initBinTree() {
this.tree = null;
tmp1Str = new String();
tmp2Str = new String();
tmp3Str = new String();
nodeList = new Vector();
}
private void hideMovingNode() {
movingNode = new Node(-1);
}
/**
* Re-assign the heap using the array of weights passed in as the
* parameter.
* @param a Array of weight for the newly re-assigned heap.
*/
public void setBinTree(int[] a) {
if (a.length > posnList.size())
calNodesCoord(a.length);
tree = null;
nodeList = new Vector();
for (int i = 0; i < a.length; i++)
insert(new Node(a[i]));
} // setData()
private void insert(Node node) {
nodeList.addElement(node);
if (posnList.size() >= nodeList.size()) {
node.setX( ((Node)posnList.elementAt(nodeList.size()-1)).getX() );
node.setY( ((Node)posnList.elementAt(nodeList.size()-1)).getY() );
}
if (tree == null) {
tree = node;
} else {
// locate blank branch to link to this node
for (int i = 0; i < nodeList.size()-1; i++) {
Node n = (Node)nodeList.elementAt(i);
if (n.getLeftNode() == null) {
n.setLeftNode(node);
break;
} else if (n.getRightNode() == null) {
n.setRightNode(node);
break;
}
}
}
}
public void animateInsertNode(int srcX, int srcY, int posn) {
Node posnNode = (Node)posnList.elementAt(posn-1);
for (int i = 0; i < 10; i++) {
obsAnim.moveCom(srcX + (i+1)*(posnNode.getX() - 100 - srcX)/10,
srcY + (i+1)*(posnNode.getY() - 50 - srcY)/10);
}
}
public void insertNodeAt(Node node, int posn) {
node.setX( ((Node)posnList.elementAt(posn-1)).getX() );
node.setY( ((Node)posnList.elementAt(posn-1)).getY() );
if (parent(posn) > 0) {
Node posnNode = (Node)posnList.elementAt(parent(posn)-1);
Node parentNode = null;
for (int i = 0; i < nodeList.size(); i++) {
parentNode = (Node)nodeList.elementAt(i);
if (parentNode.getX() == posnNode.getX() && parentNode.getY() == posnNode.getY())
break;
}
if (left(parent(posn)) == posn)
parentNode.setLeftNode(node);
else
parentNode.setRightNode(node);
}
nodeList.addElement(node);
}
/**
* Re-assign the weight of node i according to the parameters.
* @param i The node, which weight is going to be re-assigned.
* @param val The new weight to be set.
*/
public void setNode(int i, int val) {
((Node)nodeList.elementAt(i)).setWeight(val);
}
private void calNodesCoord(int size) {
// count max number of nodes needed
int i = 0; int sum = power(2, i++);
while (sum < size)
sum += power(2, i++);
max_node_per_level = power(2, i-1);
depth = i-1;
int max_nodes = sum;
// insert nodes with no value into position tree
Node backTree = tree; // backup current tree
Vector backNodeList = nodeList; nodeList = new Vector();
posnList = new Vector();
for (int j = 0; j < max_nodes; j++) {
Node node = new Node(-1);
insert(node);
}
posn = tree;
posnList = nodeList;
tree = backTree;
nodeList = backNodeList;
// assign Y
int curDepth = 0; sum = power(2, 0);
int offset = drawingPanel.getOffset() + 340;
//int yStart = drawingPanel.getPanelHeight/2 -100 - depth*20;
int yStart = drawingPanel.getOffset() + 300;
for (int j = 0; j < posnList.size(); j++) {
Node node = (Node)posnList.elementAt(j);
if ( (j+1) > sum) {
curDepth++; sum += power(2, curDepth);
}
node.setDepth(curDepth);
node.setY( yStart + curDepth*40 );
// assign X for bottom level
if (curDepth == depth) {
node.setX( 22 + offset ) ;
offset = node.getX();
}
}
// assign remaining X
for (int j = posnList.size() - 1; j >= 0; j--) {
Node node = (Node)posnList.elementAt(j);
if (node.getDepth() == depth)
continue;
if (node.getLeftNode() != null && node.getDepth() == depth-1) {
node.setX( node.getLeftNode().getX() + 12 );
} else if (node.getLeftNode() != null &&
node.getRightNode() != null) {
node.setX( (node.getLeftNode().getX() + node.getRightNode().getX())/2 );
} else {
// both children null -> can only at depth - 1
int l = left(j+1);
}
}
}
/* ------------------ Animation for Opt Bin Search Tree ---------------- */
public void highlightLeftRightSubtree(OBSearch obs,
int left, int c_root, int right) {
if (drawingPanel.getNoAnim())
return;
// highlight left subtree
Node rootNode = getNodeAt(1);
Node leftSubtree = getNodeAt(2);
if (leftSubtree != null && !leftSubtree.isLeaf()) {
highlightNode(leftSubtree);
redraw();
obsAnim.setCom("Left subtree is optimal...",
leftSubtree.getX() - 150, leftSubtree.getY() + 90);
// break off the link to parent first;
rootNode.setLeftNode(null);
int destX = leftSubtree.getX() - 3; int destY = leftSubtree.getY();
moveNode(leftSubtree, 0, 10); redraw();
moveNode(leftSubtree, 0, 10); redraw();
moveNode(leftSubtree, 0, 10); redraw();
if (obs.CostSubTree(left, c_root - 1) > 0) {
obs.cost.setHighlight2(left, c_root-1);
redraw();
obsAnim.setCom("The optimal cost for this subtree is: " +
obs.CostSubTree(left, c_root-1) +
", obtained from the cost matrix...");
tmp1Str = new String(""+obs.CostSubTree(left, c_root-1));
int srcX = tmp1X =
drawingPanel.getOffset() + (left+1)*(horizSpace+2);
int srcY = tmp1Y =
drawingPanel.getOffset() + 10 + (c_root)*(vertSpace+2);
redraw();
for (int i = 0; i < 10; i++) {
tmp1X += (destX - srcX)/10;
tmp1Y += (destY - srcY)/10;
redraw();
}
tmp1X = destX;
tmp2X = destX;
obs.frame.waitStep();
obs.cost.restoreHighlight2(left, c_root-1);
} else
obs.frame.waitStep();
obsAnim.setCom("This cost + sum of all node frequencies = " +
"subtree cost when attached to a parent = " +
obs.CostSubTree(left, c_root-1) + " + " +
sumNodeWeight(leftSubtree),
drawingPanel.getOffset(), leftSubtree.getY() - 120);
tmp1Str = new String("+" +
sumNodeWeight(leftSubtree)); redraw();
tmp1X -= 8; redraw();
tmp1Str = new String("=");
tmp1X -= 8; redraw();
tmp1Str = new String(""+(obs.CostSubTree(left, c_root-1)+
sumNodeWeight(leftSubtree))); redraw();
tmp1X -= 8; redraw();
tmp1X -= 8; tmp1Y = destY; redraw();
moveNode(leftSubtree, 0, -10); redraw();
moveNode(leftSubtree, 0, -10); redraw();
moveNode(leftSubtree, 0, -10); redraw();
rootNode.setLeftNode(leftSubtree);redraw();
obs.frame.waitStep();
obsAnim.hideCom();
restoreNode(leftSubtree);
redraw();
}
// highlight right subtree
Node rightSubtree = getNodeAt(3);
if (rightSubtree != null && !rightSubtree.isLeaf()) {
highlightNode(rightSubtree);
redraw();
obsAnim.setCom("Right subtree is optimal...",
rightSubtree.getX() - 20, rightSubtree.getY() + 90);
// break off the link to parent
rootNode.setRightNode(null);
int destX = rightSubtree.getX() - 3; int destY = rightSubtree.getY();
moveNode(rightSubtree, 0, 10); redraw();
moveNode(rightSubtree, 0, 10); redraw();
moveNode(rightSubtree, 0, 10); redraw();
if (obs.CostSubTree(c_root+1, right) > 0) {
obs.cost.setHighlight2(c_root+1, right);
redraw();
obsAnim.setCom("The optimal cost for this subtree is: " +
obs.CostSubTree(c_root+1, right) + "...",
rightSubtree.getX() - 120, rightSubtree.getY() + 90);
tmp2Str = new String(""+obs.CostSubTree(c_root+1, right));
int srcX = tmp2X =
drawingPanel.getOffset() + (c_root+2)*(horizSpace+2);
int srcY = tmp2Y =
drawingPanel.getOffset() + 10 + (right+1)*(vertSpace+2);
redraw();
for (int i = 0; i < 10; i++) {
tmp2X += (destX - srcX)/10;
tmp2Y += (destY - srcY)/10;
redraw();
}
tmp2X = destX;
tmp2Y = destY;
obs.frame.waitStep();
obs.cost.restoreHighlight2(c_root+1, right);
} else
obs.frame.waitStep();
obsAnim.setCom("Subtree cost at depth + 1 " +
"(attached to a parent node) = " +
obs.CostSubTree(c_root+1, right) + " + " +
sumNodeWeight(rightSubtree),
drawingPanel.getOffset() + 150, rightSubtree.getY() - 120);
tmp2Str = new String("+" +
sumNodeWeight(rightSubtree)); redraw();
tmp2X += 8; redraw();
tmp2Str = new String("=");
tmp2X += 8; redraw();
tmp2Str = new String(""+(obs.CostSubTree(c_root+1, right) +
sumNodeWeight(rightSubtree))); redraw();
tmp2X += 8; redraw();
tmp2X += 8; tmp2Y = destY; redraw();
moveNode(rightSubtree, 0, -10); redraw();
moveNode(rightSubtree, 0, -10); redraw();
moveNode(rightSubtree, 0, -10); redraw();
// reattach root
rootNode.setRightNode(rightSubtree); redraw();
obs.frame.waitStep();
obsAnim.hideCom();
restoreNode(rightSubtree);
redraw();
}
// get 3rd cost from root
tmp3Str = new String("" + rootNode.getWeight());
tmp3X = rootNode.getX() - 15;
tmp3Y = rootNode.getY() + 5;
redraw();
tmp3X -= 10; redraw();
tmp3X -= 10; redraw();
if (leftSubtree != null && tmp1Str.length() == 0) {
obsAnim.setCom("Left node cost at depth 1...",
leftSubtree.getX() - 160, leftSubtree.getY() - 40);
tmp1Str = new String("" + leftSubtree.getWeight());
tmp1X = leftSubtree.getX() - 15;
tmp1Y = leftSubtree.getY() + 5;
redraw();
tmp1Str = tmp1Str.concat("x2");
tmp1X -= 10; redraw();
tmp1Str = new String("" + 2*leftSubtree.getWeight());
tmp1X -= 10; redraw();
obsAnim.hideCom();
}
if (rightSubtree != null && tmp2Str.length() == 0) {
obsAnim.setCom("Right node cost at depth 1...",
rightSubtree.getX() - 20, rightSubtree.getY() - 40);
tmp2Str = new String("" + rightSubtree.getWeight());
tmp2X = rightSubtree.getX();
tmp2Y = rightSubtree.getY() + 5;
redraw();
tmp2Str = tmp2Str.concat("x2");
tmp2X += 10; redraw();
tmp2Str = new String("" + 2*rightSubtree.getWeight());
tmp2X += 10; redraw();
tmp2X += 10; redraw();
obsAnim.hideCom();
}
// adding cost
int total = Integer.parseInt(tmp3Str);
if (tmp1Str.length() > 0)
total += Integer.parseInt(tmp1Str);
if (tmp2Str.length() > 0)
total += Integer.parseInt(tmp2Str);
// merge left and right cost into root cost
obsAnim.setCom("Calculating cost for this subtree...",
rootNode.getX() - 300, rootNode.getY() - 40);
tmp1Y += (tmp3Y - tmp1Y) /2;
tmp2Y += (tmp3Y - tmp2Y) /2;
redraw();
tmp1Y = tmp2Y = tmp3Y;
redraw();
int src1 = tmp1X; int src2 = tmp2X;
for (int i = 0; i < 5; i++) {
tmp1X += (tmp3X - src1)/5;
tmp2X += (tmp3X - src2)/5;
redraw();
}
tmp1Str = new String(); tmp2Str = new String();
tmp3Str = new String(""+total);
redraw();
} // highlightLeftRightSubtree()
public void tree2Matrices(int left, int right) {
if (drawingPanel.getNoAnim())
return;
int dest1X = drawingPanel.getOffset() + (left+1)*(horizSpace+2);
int dest1Y = drawingPanel.getOffset() + 10 + (right+1)*(vertSpace+2);
int dest2X = drawingPanel.getOffset() + 380 + (left+1)*(horizSpace+2);
int dest2Y = drawingPanel.getOffset() + 10 + (right+1)*(vertSpace+2);
tmp3X -= 10; redraw();
tmp3X -= 10; redraw();
tmp3X -= 10; redraw();
tmp3X -= 10; redraw();
tmp1Str = new String(((Node)nodeList.firstElement()).getLabel());
tmp1X = tmp3X; tmp1Y = tmp3Y;
tmp1X += 10; redraw();
tmp1X += 10; redraw();
tmp1X += 10; redraw();
tmp1X += 10; redraw();
int src1X = tmp3X; int src1Y = tmp3Y;
int src2X = tmp1X; int src2Y = tmp1Y;
for (int i = 0; i < 10; i++) {
tmp3X += (dest1X - src1X)/10;
tmp3Y += (dest1Y - src1Y)/10;
tmp1X += (dest2X - src2X)/10;
tmp1Y += (dest2Y - src2Y)/10;
redraw();
}
tmp3X = dest1X; tmp3Y = dest1Y;
tmp1X = dest2X; tmp1Y = dest2Y; redraw();
tmp3Str = new String();
tmp1Str = new String();
}
/* ------------------------ Utils -------------------- */
/**
* Performs the exponent of num
to the power of
* pow
.
* @param num Base.
* @param pow Exponent.
*/
public int power(int num, int pow) {
int result = 1;
for (int i = 0; i < pow; i++)
result *= num;
return result;
}
/**
* @return The position of the parent of node i.
* @param i The node, whose parent is of interest.
*/
public int parent(int i) {
return (i/2);
}
/**
* Returns the left child of node i.
*/
public int left(int i) {
return (2*i);
}
/**
* Returns the right child of node i.
*/
public int right(int i) {
return (2*i + 1);
}
/* ------------------------ Graphical Primitives ------------------ */
/**
* Draws all graphical objects within this class.
* @param g Graphical context.
*/
public void draw(Graphics g) {
drawTree(g);
}
/**
* Draws all graphical objects within this class.
* @param g Graphical context.
*/
public void drawTree(Graphics g) {
if (tmp1Str.length() > 0)
drawBox(g, tmp1X, tmp1Y, tmp1Str,
Color.white, Color.black, fixFont);
if (tmp2Str.length() > 0)
drawBox(g, tmp2X, tmp2Y, tmp2Str,
Color.white, Color.black, fixFont);
if (tmp3Str.length() > 0)
drawBox(g, tmp3X, tmp3Y, tmp3Str,
Color.white, Color.black, fixFont);
for (int i = 0; i < nodeList.size(); i++) {
Node node = (Node)nodeList.elementAt(i);
drawNode(g, node);
}
if (movingNode.getWeight() > -1)
drawNode(g, movingNode);
}
public void drawBox(Graphics g, int x, int y, String str,
Color fg, Color bg, Font font) {
String blank = new String();
for (int i = 0; i < 4-str.length(); i++)
blank = blank.concat(" ");
g.setColor(bg);
g.fillRect(x, y, horizSpace, vertSpace);
g.setColor(Color.black);
g.drawRect(x, y, horizSpace, vertSpace);
g.setColor(fg);
g.setFont(font);
g.drawString(blank + str, x + 2, y + vertSpace - 4);
}
/**
* Draw an arrowed line segment using the array of points.
* @param g Graphical context
* @param points The vortices of the line segment.
* An arrow head will be drawn using the last point in the array at the tip.
*/
public void drawArrow(Graphics g, Point[] points) {
// remember: no drawPolyline in jdk1.0.*
int[] axPoints = new int[3], ayPoints = new int[3];
g.setColor( Color.magenta );
if (points.length < 3) {
Point endArrow = points[1], startArrow = points[0];
if (endArrow.y == startArrow.y) {
g.drawLine(startArrow.x, startArrow.y, endArrow.x, endArrow.y);
axPoints[0] = endArrow.x; ayPoints[0] = endArrow.y;
int unit = (endArrow.x - startArrow.x)/
Math.abs(endArrow.x - startArrow.x);
axPoints[1] = endArrow.x - unit*2;
ayPoints[1] = endArrow.y - 2;
axPoints[2] = endArrow.x - unit*2;
ayPoints[2] = endArrow.y + 2;
g.fillPolygon(axPoints, ayPoints, 3);
} else if (endArrow.x == startArrow.x) {
g.drawLine(startArrow.x, startArrow.y, endArrow.x, endArrow.y);
axPoints[0] = endArrow.x; ayPoints[0] = endArrow.y;
int unit = (endArrow.y - startArrow.y)/
Math.abs(endArrow.y - startArrow.y);
axPoints[1] = endArrow.x - 1;
ayPoints[1] = endArrow.y - unit*2;
axPoints[2] = endArrow.x + 2;
ayPoints[2] = endArrow.y - unit*2;
g.fillPolygon(axPoints, ayPoints, 3);
}
} else if (points.length == 3) {
// draw a line for the first and second points then use
// drawArrow to draw the remaining segment
g.drawLine(points[0].x, points[0].y, points[1].x, points[1].y);
Point[] line = new Point[2];
line[0] = points[1];
line[1] = points[2];
drawArrow(g, line);
}
}
/**
* @param node The root node of the tree
* @return The width of the tree in the number of pixels.
*/
public int treeWidth(Node node) {
return (rightMostPosn(node) - leftMostPosn(node));
}
/**
* @param node The root node of the tree
* @return The left most position of the tree
*/
public int leftMostPosn(Node node) {
if (node.isLeaf())
return node.getX();
else
return leftMostPosn(node.getLeftNode());
}
/**
* @param node The root node of the tree
* @return The right most position of the tree
*/
public int rightMostPosn(Node node) {
if (node.isLeaf())
return (node.getX() + 20);
else
return rightMostPosn(node.getRightNode());
}
/**
* @param node The root node of the tree
* @return The height of the tree in the number of pixels.
*/
public int treeHeight(Node node) {
return (bottomMostPosn(node) - node.getY());
}
/**
* @param node The root node of the tree
* @return The bottom most position of the tree
*/
public int bottomMostPosn(Node node) {
if (node == null) return 0;
if (node.isLeaf())
return (node.getY() + 30);
else {
int rightBottom = bottomMostPosn(node.getRightNode());
int leftBottom = bottomMostPosn(node.getLeftNode());
return (rightBottom > leftBottom ? rightBottom : leftBottom);
}
}
/**
* Drawing a leaf node of the heap.
* @param g Graphical context
* @param node The node to be drawn
*/
public void drawLeafNode(Graphics g, Node node) {
int x = node.getX(); int y = node.getY();
int weight = node.getWeight();
if (node.highlight)
g.setColor(Color.black);
else
g.setColor( Color.blue );
g.fillRect(x, y, 20, 30);
g.setColor(Color.black);
g.drawRect(x, y, 20, 30);
if (node.getLabel().length() > 0) {
g.setColor( Color.yellow );
g.setFont( hugeFont );
g.drawString(node.getLabel(), node.getX() + 5, node.getY() + 12);
}
g.setColor( Color.white );
g.setFont( bigFont );
g.drawString(""+node.getWeight(), node.getX() + 2, node.getY()+27);
}
/**
* Draw a node of the array representation of the heap.
* @param g Graphical context
* @param x The x coordinate of the top left corner of the node
* @param y The y coordinate of the top left corner of the node
* @param node The node to be drawn
*/
public void drawArrayNode(Graphics g, int x, int y, Node node) {
int weight = node.getWeight();
if (node.highlight)
g.setColor(Color.black);
else
g.setColor( Color.red );
g.fillRect(x, y, 20, 30);
g.setColor(Color.black);
g.drawRect(x, y, 20, 30);
g.setFont(hugeFont);
g.setColor( Color.yellow );
g.drawString(""+weight, x+2, y+25);
}
/**
* Drawing a node based on the input parameters.
* @param g Graphical context
* @param node The node to be drawn
*/
public void drawNode(Graphics g, Node node) {
if (node.highlight)
g.setColor(Color.black);
else
g.setColor( darkgreen );
g.fillRect(node.getX(), node.getY(), 20, 30);
g.setColor(Color.black);
g.drawRect(node.getX(), node.getY(), 20, 30);
if (node.getLabel().length() > 0) {
g.setColor( Color.yellow );
g.setFont( hugeFont );
g.drawString(node.getLabel(), node.getX() + 5, node.getY() + 12);
}
g.setColor( Color.white );
g.setFont( bigFont );
g.drawString(""+node.getWeight(), node.getX() + 2, node.getY()+27);
// draw links to children
if (node.getLeftNode() != null) {
g.setColor( Color.black );
g.drawLine(node.getX() + 6, node.getY() + 30,
node.getLeftNode().getX() + 10, node.getLeftNode().getY());
if (node.highlightLeft) {
g.drawLine(node.getX() + 5, node.getY() + 30,
node.getLeftNode().getX() + 9, node.getLeftNode().getY());
g.drawLine(node.getX() + 4, node.getY() + 30,
node.getLeftNode().getX() + 8, node.getLeftNode().getY());
}
}
if (node.getRightNode() != null) {
g.setColor( Color.black );
g.drawLine(node.getX() + 14, node.getY() + 30,
node.getRightNode().getX() + 10, node.getRightNode().getY());
if (node.highlightRight) {
g.drawLine(node.getX() + 15, node.getY() + 30,
node.getRightNode().getX() + 11, node.getRightNode().getY());
g.drawLine(node.getX() + 16, node.getY() + 30,
node.getRightNode().getX() + 12, node.getRightNode().getY());
}
}
}
/**
* 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 moveNode(Node node, int dx, int dy) {
if (node == null) return;
node.moveNode(dx, dy);
}
public void highlightNode(Node node) {
node.highlight = true;
if (node.getLeftNode() != null)
highlightNode(node.getLeftNode());
if (node.getRightNode() != null)
highlightNode(node.getRightNode());
}
public void restoreNode(Node node) {
node.highlight = false;
if (node.getLeftNode() != null)
restoreNode(node.getLeftNode());
if (node.getRightNode() != null)
restoreNode(node.getRightNode());
}
public Node getNodeAt(int posn) {
Node posnNode = (Node)posnList.elementAt(posn-1);
for (int i = 0; i < nodeList.size(); i++) {
Node node = (Node)nodeList.elementAt(i);
if (node.getX() == posnNode.getX() && node.getY() == posnNode.getY()) {
return node;
}
}
return null;
}
public int sumNodeWeight(Node node) {
if (node == null) return 0;
return (sumNodeWeight(node.getRightNode()) +
sumNodeWeight(node.getLeftNode()) +
node.getWeight());
}
Node root = null;
public void setRoot(Node node) {
this.root = node;
}
public int getX() {
return getNodeAt(1).getX();
}
public int getY() {
return getNodeAt(1).getY();
}
public void move(int x, int y) {
Point orig = new Point(0, 0);
if (root != null) {
orig.x = root.getX();
orig.y = root.getY();
root.move(x, y);
} else {
root = (Node)nodeList.firstElement();
if (root != null) {
orig.x = root.getX();
orig.y = root.getY();
root.move(x, y);
}
}
if (root != null) {
int dx = x - orig.x;
int dy = y - orig.y;
if (tmp1Str.length() > 0) {
tmp1X += dx;
tmp1Y += dy;
}
if (tmp2Str.length() > 0) {
tmp2X += dx;
tmp2Y += dy;
}
if (tmp3Str.length() > 0) {
tmp3X += dx;
tmp3Y += dy;
}
}
}
}