AnimationCanvas.java
/***********************************************************/
/* AnimationCanvas class */
/* A MergeSort demonstration algorithm */
/* By JungSig Min attending Myong Ji University */
/***********************************************************/
/***********************************************************/
class AnimationCanvas extends Canvas {
static final int dBarWidth=20; //constant variables for the positions
static final int dBarHeight=6; // of the animation canvas
static final int dBarGap=5;
static final int dBarSpace=dBarWidth+dBarGap;
static final int originX1=20;
static final int originY1=140;
static final int originX2=20;
static final int originY2=284;
static final int originX3=20;
static final int originY3=315;
Color skyBlue=new Color(116,224,255); //different color definations
Color sortedColor=new Color(255,159,77);
Color unsortedColor=new Color(0,91,131);
Color rocketColor=new Color(255,122,100);
MergeSort applet; //declare mergesort applet
Image offscreenImage; //offscreenImage for double buffering
Graphics offscreenGraphics; //offscreenGraphics for double buffering
int moveX,moveY,moveWidth,moveHeight; //movement parameters
boolean showFlame; //whether to show fire flames of rocket
//constructor of AnimationCanvas
public AnimationCanvas ( MergeSort applet ) {
this.applet = applet; //introduce MergeSort applet
setBackground (skyBlue); //setBackground color
}
public void init() {
// offscreenImage= createImage(this.size().width,this.size().height);
// offscreenGraphics=offscreenImage.getGraphics();
}
//get prefered size
public Dimension preferredSize () {
return new Dimension (200, 100);
}
//get minimum size
public Dimension minimumSize () {
return preferredSize ();
}
//bar movement like a rocket
public void move(int workIdx, int arrayIdx ){
int i; //some local variables
int value=applet.workArray[workIdx];
int X1=originX1+(applet.low[applet.level]+workIdx)*dBarSpace;
int X2=originX2+(applet.low[applet.level]+arrayIdx)*dBarSpace;
int Y1=originY2-value*dBarHeight;
int Y2=originY1-value*dBarHeight;
moveY=Y1;
moveWidth=dBarWidth;
moveHeight=value*dBarHeight;
showFlame=false; //don't shower fire flame when move horizontally
if (X1X2)
for ( moveX=X1; moveX>=X2;moveX-=5) {//move horizontally from right to left
repaint(); //repaint the animation canvas
}
moveX=X2;
i=0;
for (moveY=Y1; moveY>=Y2;moveY-=8) {//move vertically
if (i%2==0)
showFlame=true; //show flame then not show flame to make it flashing
else
showFlame=false;
i++;
repaint(); //repaint the animation canvas
}
}
//paint function on the Graphics
public void paint(Graphics g) {
char temp[]; //some local variables
int value;
int pivot;
int workLength;
Polygon poly;
//text strings on the canvas
g.drawString("Sorting Array a[ ]",originX1+150,originY1+35);
g.drawString("Temp Array working[ ]",originX2+130,originY2+25);
g.drawString("Working Range at Levels of Recursion",originX1+80,originY3+75);
g.drawString("Complexity: Comparison Counter ="+applet.compCount+" Assignment Counter ="+applet.assignCount,originX1,originY3+100);
//animation for Working Range at Levels of Recursion
for (int i=1;i<=applet.level;i++) {
g.setColor(Color.black);
g.drawString(""+i,2,originY3+i*10);
g.setColor(Color.gray);
workLength=applet.high[i]-applet.low[i]+1;
if (workLength>0)
g.fillRect(originX3+applet.low[i]*dBarSpace,originY3+i*10-5, workLength*dBarSpace,6 );
}
//animation for Sorting Array a[ ]
for (int i=0;i=applet.low[applet.level] && i<=applet.high[applet.level])
g.setColor(sortedColor);
else
g.setColor(unsortedColor);
g.drawString(""+value,originX1+i*dBarSpace,originY1+20);
g.fillRect(originX1+i*dBarSpace,originY1-value*dBarHeight,dBarWidth,value*dBarHeight);
}
//animation for Temp Array working[ ]
if (applet.showWork){
pivot=applet.workLength/2;
for (int i=0;i<applet.workLength;i++) {
value=applet.workArray[i];
if (i<applet.m1Idx)
g.setColor(Color.blue);
else if (i< pivot)
g.setColor(Color.yellow);
else if (i< applet.m2Idx)
g.setColor(Color.blue);
else
g.setColor(Color.orange);
g.fillRect(originX2+(i+applet.low[applet.level])*dBarSpace,originY2-value*dBarHeight,dBarWidth,value*dBarHeight);
if (i==applet.m1Idx)
g.drawString("m1="+i,originX2+(i+applet.low[applet.level])*dBarSpace,originY2+10);
if (i==applet.m2Idx)
g.drawString("m2="+i,originX2+(i+applet.low[applet.level])*dBarSpace,originY2+18);
}
}
//animation for bar movement like a rocket
if (applet.moveBar) {
g.setColor(rocketColor);
int Xs[]= {moveX,moveX+moveWidth/2,moveX+moveWidth,moveX+moveWidth,moveX};
int Ys[]= {moveY,moveY-moveWidth,moveY,moveY+moveHeight,moveY+moveHeight};
int pts=Xs.length;
poly=new Polygon(Xs,Ys,pts);
g.fillPolygon(poly);
if (showFlame) {
for (int i=moveX;i<=moveX+moveWidth;i++){
if (i%3==0)
g.setColor(Color.yellow);
else if (i%2==1)
g.setColor(Color.red);
else
g.setColor(Color.white);
g.drawLine(i,moveY+moveHeight+5,i,moveY+moveHeight+20);
}
}
}
}
//override repaint() to support double buffering
public void repaint()
{
Image image = this.createImage(size().width, size().height);
Graphics g = image.getGraphics();
g.setColor(this.getBackground());
g.fillRect(0,0,size().width,size().height);
g.setColor(this.getForeground());
paint(g);
this.getGraphics().drawImage(image,0,0,null);
}
}