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);
  }
}