import java.awt.*; import Node; import Tree; import MainWin; // This class define the display area on which the tree is // drawn. public class Display extends Canvas { public final static int Full = 0; public final static int Buble = 1; private MainWin Parent; private Image offImage; // for double buffering use private Graphics offGraphic; private float hgap,vgap; // use for the tree drawing, tell the // horizontal & vertical gaps between // the nodes. // constructor create the object. public Display(MainWin p) { Parent = p; } // This method draw the tree. if the window size is changes the drawing // is updated respectively public synchronized void paint(Graphics g) { drawTree(); } // This method draw again the off image since I do not want that each // repaint will draw the tree again. public void update(Graphics g) { // painting the off image on the screen g.drawImage(offImage,0,0,this); } // This method draws the tree by calling the recursive method drawNode // with the root as parameter. public synchronized void drawTree() { Graphics g; g = getGraphics(); // I create a new image if anyone change the size of // the window so the drawing will change correspondingly. offImage = createImage(size().width,size().height); offGraphic = offImage.getGraphics(); // Clearing the offimage. offGraphic.setColor(new Color(180,180,180)); offGraphic.fillRect(0,0,size().width,size().height); // setting the original color. offGraphic.setColor(g.getColor()); hgap = size().width / 2; vgap =(float)((size().height-50) / (2*Math.log(Tree.maxNodes+1))); // drawing the offimage if (Parent.tree.getRoot() != Tree.treeNull) drawNode(Parent.tree.getRoot(),Math.round(hgap),50); // painting the off image on the screen g.drawImage(offImage,0,0,this); } // This is a recurcive method that draw a node and call drawNode to // draw it's children. public void drawNode(Node node,int x,int y) { hgap = hgap / 2; if (node.getNode(Node.Left_son) != Tree.treeNull) { offGraphic.setColor(Color.black); offGraphic.drawLine(x,y,Math.round(x-hgap),Math.round(y+vgap)); drawNode(node.getNode(Node.Left_son), Math.round(x-hgap),Math.round(y+vgap)); } if (node.getNode(Node.Right_son) != Tree.treeNull) { offGraphic.setColor(Color.black); offGraphic.drawLine(x,y,Math.round(x+hgap),Math.round(y+vgap)); drawNode(node.getNode(Node.Right_son), Math.round(x+hgap),Math.round(y+vgap)); } if (node.isBold()) // draw a mark on the node. { offGraphic.setColor(Color.blue); /* Changed BPW offGraphic.fillOval(x-17,y-17,34,34); */ offGraphic.fillOval(x-25,y-17,50,34); node.setBold(Node.Reg); } offGraphic.setFont(new Font("TimesRoman",Font.PLAIN,20)); if (node.getColor() == Node.Black) { offGraphic.setColor(Color.black); /* Changed BPW offGraphic.fillOval(x-12,y-12,24,24); */ offGraphic.fillOval(x-20,y-12,40,24); offGraphic.setColor(Color.red); } else { offGraphic.setColor(Color.red); /* Changed BPW offGraphic.fillOval(x-12,y-12,24,24); */ offGraphic.fillOval(x-20,y-12,40,24); offGraphic.setColor(Color.black); } if (node.getKey() < 10) // draw the key on the node offGraphic.drawString(Integer.toString(node.getKey()),x-4,y+7); else if (node.getKey() < 100) offGraphic.drawString(Integer.toString(node.getKey()),x-9,y+7); else /* New case added by BP Weems */ offGraphic.drawString(Integer.toString(node.getKey()),x-14,y+7); hgap = 2*hgap; node.setLocX(x); // update the node location for tokenMove and node.setLocY(y); // nodeMove methods. } // This method draw a token move fron node src to node dest. // the drawing is done in XOR mode. public void tokenMove(Node src,Node dest) { Graphics g; int srcX,srcY,destX,destY,currX,currY,lastX,lastY; int i; float m; g = getGraphics(); offGraphic.setColor(new Color(180,180,180)); offGraphic.setXORMode(Color.white); offGraphic.setXORMode(Color.blue); srcX = src.getLocX(); srcY = src.getLocY(); destX = dest.getLocX(); destY = dest.getLocY(); m = ((float)(destY-srcY)) / ((float)(destX-srcX)); lastY = srcY; lastX = srcX; // The drawing is done acording to low slap( 'SHIPUA' ) to get // the moving fill. if abs(m)<1 the loop is on the x coordinate // otherwise the loop is on the y coordinate. if ((m < 1) && (m > -1)) { if (srcX < destX) i = 5; else i = -5; offGraphic.fillOval(lastX-5,lastY-5,10,10); update(g); for (currX = srcX+i ; (currX*i) <= (destX*i) ; currX+=i) { currY = Math.round((currX-srcX)*m) + srcY; offGraphic.fillOval(lastX-5,lastY-5,10,10); offGraphic.fillOval(currX-5,currY-5,10,10); lastX = currX; lastY = currY; update(g); } offGraphic.fillOval(lastX-5,lastY-5,10,10); update(g); } else { if (srcY < destY) i = 5; else i = -5; offGraphic.fillOval(lastX-5,lastY-5,10,10); update(g); for (currY = srcY+i ; (currY*i) <= (destY*i) ; currY+=i) { currX = Math.round((currY-srcY)/m) + srcX; offGraphic.fillOval(lastX-5,lastY-5,10,10); offGraphic.fillOval(currX-5,currY-5,10,10); lastX = currX; lastY = currY; update(g); } offGraphic.fillOval(lastX-5,lastY-5,10,10); update(g); } } // This method draw a buble node or full node move from src to dest // shape can be Full or Bouble. // it is quit similar to the tokenMove method. // again the drawing done in XOR mode. public void nodeMove(Node src,Node dest,int shape) { Graphics g; int srcX,srcY,destX,destY,currX,currY,lastX,lastY; int i; float m; g = getGraphics(); offGraphic.setColor(new Color(180,180,180)); offGraphic.setXORMode(Color.white); if ((shape == Full) && (src.getColor() == Node.Red)) offGraphic.setXORMode(Color.red); else offGraphic.setXORMode(Color.black); srcX = src.getLocX(); srcY = src.getLocY(); destX = dest.getLocX(); destY = dest.getLocY(); m = ((float)(destY-srcY)) / ((float)(destX-srcX)); lastY = srcY; lastX = srcX; if ((m < 1) && (m > -1)) { if (srcX < destX) i = 5; else i = -5; if (shape == Full) /* Changed BPW offGraphic.fillOval(lastX-12,lastY-12,24,24); */ offGraphic.fillOval(lastX-20,lastY-12,40,24); else { /* Changed BPW offGraphic.drawOval(lastX-12,lastY-12,24,24); offGraphic.drawString(Integer.toString(src.getKey()),lastX-7,lastY+7); */ offGraphic.fillOval(lastX-20,lastY-12,40,24); if (src.getKey() < 10) // draw the key on the node offGraphic.drawString(Integer.toString(src.getKey()),lastX-4,lastY+7); else if (src.getKey() < 100) offGraphic.drawString(Integer.toString(src.getKey()),lastX-9,lastY+7); else /* New case added by BP Weems */ offGraphic.drawString(Integer.toString(src.getKey()),lastX-14,lastY+7); } update(g); for (currX = srcX+i ; (currX*i) <= (destX*i) ; currX+=i) { currY = Math.round((currX-srcX)*m) + srcY; if (shape == Full) { /* Changed BPW offGraphic.fillOval(lastX-12,lastY-12,24,24); offGraphic.fillOval(currX-12,currY-12,24,24); */ offGraphic.fillOval(lastX-20,lastY-12,40,24); offGraphic.fillOval(currX-20,currY-12,40,24); } else { /* Changed BPW offGraphic.drawOval(lastX-12,lastY-12,24,24); offGraphic.drawString(Integer.toString(src.getKey()),lastX-7,lastY+7); */ offGraphic.drawOval(lastX-20,lastY-12,40,24); if (src.getKey() < 10) // draw the key on the node offGraphic.drawString(Integer.toString(src.getKey()),lastX-4,lastY+7); else if (src.getKey() < 100) offGraphic.drawString(Integer.toString(src.getKey()),lastX-9,lastY+7); else /* New case added by BP Weems */ offGraphic.drawString(Integer.toString(src.getKey()),lastX-14,lastY+7); /* Changed BPW offGraphic.drawOval(currX-12,currY-12,24,24); offGraphic.drawString(Integer.toString(src.getKey()),currX-7,currY+7); */ offGraphic.drawOval(currX-20,currY-12,40,24); if (src.getKey() < 10) // draw the key on the node offGraphic.drawString(Integer.toString(src.getKey()),currX-4,currY+7); else if (src.getKey() < 100) offGraphic.drawString(Integer.toString(src.getKey()),currX-9,currY+7); else /* New case added by BP Weems */ offGraphic.drawString(Integer.toString(src.getKey()),currX-14,currY+7); } update(g); lastX = currX; lastY = currY; } if (shape == Full) /* Changed BPW offGraphic.fillOval(lastX-12,lastY-12,24,24); */ offGraphic.fillOval(lastX-20,lastY-12,40,24); else { /* Changed BPW offGraphic.drawOval(lastX-12,lastY-12,24,24); offGraphic.drawString(Integer.toString(src.getKey()),lastX-7,lastY+7); */ offGraphic.drawOval(lastX-20,lastY-12,40,24); if (src.getKey() < 10) // draw the key on the node offGraphic.drawString(Integer.toString(src.getKey()),lastX-4,lastY+7); else if (src.getKey() < 100) offGraphic.drawString(Integer.toString(src.getKey()),lastX-9,lastY+7); else /* New case added by BP Weems */ offGraphic.drawString(Integer.toString(src.getKey()),lastX-14,lastY+7); } update(g); } else { if (srcY < destY) i = 1; else i = -1; if (shape == Full) /* Changed BPW offGraphic.fillOval(lastX-12,lastY-12,24,24); */ offGraphic.fillOval(lastX-20,lastY-12,40,24); else { /* Changed BPW offGraphic.drawOval(lastX-12,lastY-12,24,24); offGraphic.drawString(Integer.toString(src.getKey()),lastX-7,lastY+7); */ offGraphic.drawOval(lastX-20,lastY-12,40,24); if (src.getKey() < 10) // draw the key on the node offGraphic.drawString(Integer.toString(src.getKey()),lastX-4,lastY+7); else if (src.getKey() < 100) offGraphic.drawString(Integer.toString(src.getKey()),lastX-9,lastY+7); else /* New case added by BP Weems */ offGraphic.drawString(Integer.toString(src.getKey()),lastX-14,lastY+7); } update(g); for (currY = srcY+i ; (currY*i) <= (destY*i) ; currY+=i) { currX = Math.round((currY-srcY)/m) + srcX; if (shape == Full) { /* Changed BPW offGraphic.fillOval(lastX-12,lastY-12,24,24); offGraphic.fillOval(currX-12,currY-12,24,24); */ offGraphic.fillOval(lastX-20,lastY-12,40,24); offGraphic.fillOval(currX-20,currY-12,40,24); } else { /* Changed BPW offGraphic.drawOval(lastX-12,lastY-12,24,24); offGraphic.drawString(Integer.toString(src.getKey()),lastX-7,lastY+7); */ offGraphic.drawOval(lastX-20,lastY-12,40,24); if (src.getKey() < 10) // draw the key on the node offGraphic.drawString(Integer.toString(src.getKey()),lastX-4,lastY+7); else if (src.getKey() < 100) offGraphic.drawString(Integer.toString(src.getKey()),lastX-9,lastY+7); else /* New case added by BP Weems */ offGraphic.drawString(Integer.toString(src.getKey()),lastX-14,lastY+7); /* Changed BPW offGraphic.drawOval(currX-12,currY-12,24,24); offGraphic.drawString(Integer.toString(src.getKey()),currX-7,currY+7); */ offGraphic.drawOval(currX-20,currY-12,40,24); if (src.getKey() < 10) // draw the key on the node offGraphic.drawString(Integer.toString(src.getKey()),currX-4,currY+7); else if (src.getKey() < 100) offGraphic.drawString(Integer.toString(src.getKey()),currX-9,currY+7); else /* New case added by BP Weems */ offGraphic.drawString(Integer.toString(src.getKey()),currX-14,currY+7); } update(g); lastX = currX; lastY = currY; } if (shape == Full) /* Changed BPW offGraphic.fillOval(lastX-12,lastY-12,24,24); */ offGraphic.fillOval(lastX-20,lastY-12,40,24); else { /* Changed bpw offGraphic.drawOval(lastX-12,lastY-12,24,24); offGraphic.drawString(Integer.toString(src.getKey()),lastX-7,lastY+7); */ offGraphic.drawOval(lastX-20,lastY-12,40,24); if (src.getKey() < 10) // draw the key on the node offGraphic.drawString(Integer.toString(src.getKey()),lastX-4,lastY+7); else if (src.getKey() < 100) offGraphic.drawString(Integer.toString(src.getKey()),lastX-9,lastY+7); else /* New case added by BP Weems */ offGraphic.drawString(Integer.toString(src.getKey()),lastX-14,lastY+7); } update(g); } } }