AWT Animations

Animations in Applet -


An Animation is nothing but the moving objects on screen. Animation in Applet means we are going to move the images or other objects from one place to another displayed on Applet Window.
We can animate the images or other objects displayed on Applet window using the concept of multi threading, paint(), repaint() and update() methods.
Multithreading is required to update the Applet window multiple times per second so that images or objects seem moving on screen.

Animation 1 -

'Bouncing ball' or 'Moving Ball'-
Consider the following example of "Bouncing ball" or "Moving Ball" that demonstrates how to create a single ball bouncing inside an Applet.
Note the structure of the program; all animations will have the same structure.
import java.awt.*;
import java.applet.*;
public class Demo1 extends Applet implements Runnable
{
    int X = 0, Y =0, Xinc = 2, Yinc = 1;
    int ball_width = 100, ball_height = 100, aw, ah;
    Thread t;
    public void init()
    {
        aw = getSize().width;
        ah = getSize().height;
        t = new Thread(this);
    }
    public void start()
    {
        t.start();
    }
    public void run()
    {
        while(true)
        {
            X= X+Xinc;
            Y = Y+Yinc;
            repaint();
            try
            {
                Thread.sleep(10);
            }
            catch(Exception ex)
            {
                System.out.println(ex);
            }
            if((X+ball_width)>=aw || X<=0)
            {
                Xinc = Xinc*(-1);
            }
            if((Y+ball_height)>=ah || Y<=0)
            {
                Yinc = Yinc*(-1);
            }
        }

    }
    public void paint(Graphics g)
    {
        g.setColor(Color.pink);
        g.fillOval(X, Y, ball_width, ball_height);
    }


}        

Output -

"Bouncing ball" or "Moving Ball" Example Using the concept of Double Buffering -

Double Buffering is mainly used to remove flashing or flickering in images or animations. Mainly in case of animations some flickering may occur. You can also see some flickering in the above example animation too.
To make the animation smooth now we are going to use the concept of Double Buffering in the Bouncing ball animation.
import java.awt.*;
import java.applet.*;
public class Test extends Applet implements Runnable
{
    int X = 0, Y =0, Xinc = 2, Yinc = 1;
    int ball_width = 100, ball_height = 100, aw, ah;
  
    Thread t;
    Image img;
    Graphics gimg;
    public void init()
    {
        aw = getSize().width;
        ah = getSize().height;
        t = new Thread(this);
        img = createImage(aw,ah);  // create an image of applet size.
        gimg = img.getGraphics();  // get Graphics object to draw on it.
    }
    public void start()
    {
        t.start();
    }
    public void run()
    {
        while(true)
        {
            X= X+Xinc;
            Y = Y+Yinc;
            
            repaint();  // It will call to update().
            try
            {
                Thread.sleep(10);
            }
            catch(Exception ex)
            {
                System.out.println(ex);
            }
            if((X+ball_width)>=aw || X<=0)
            {
                Xinc = Xinc*(-1);
            }
            if((Y+ball_height)>=ah || Y<=0)
            {
                Yinc = Yinc*(-1);
            }
            
        }

    }
    public void update(Graphics g)  // handle redisplay.
    {
        paint(g);
    }
    public void paint(Graphics g)
    {
        gimg.clearRect(0, 0, aw, ah);    // clear the complete image. It is required to draw a new image, otherwise all images will be displayed on screen.
        gimg.setColor(Color.pink);        
        gimg.fillOval(X, Y, ball_width, ball_height);  // Draw ball of pink color on Image surface.
        g.drawImage(img, 0, 0, this);    // finally draw that image directly on Applet window. 
    }
}    

Program Description -

In the above example repaint() will first call the update() method and within update we call paint(). The update() method is used to handle the redisplay of objects on Applet screen. This method simply clears the whole object area and then call the paint() method.

Output -

Now the animation will be smooth compared to previous one.

Animation 2 -

Replacing one image in an Oval with another gradually and so on.
import java.awt.*;
import java.applet.*;
import java.awt.Image.*;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
public class Test extends Applet implements Runnable
{
    String Image_List[] = {"a.jpg","b.jpg","c.jpg", "d.jpg"}; // list of image names to be displayed in oval on Applet window.
    int pre = Image_List.length-1;   // index for current image 
    int next = 0;                                 // index for the next image
    int aw, ah;
    int x = 0;                                       
    Thread t;
    Image img;
    Graphics gimg;
    public void init()
    {
        aw = getSize().width;
        ah = getSize().height;
        t = new Thread(this);
        img = createImage(aw,ah);    // create an image for double buffering
        gimg = img.getGraphics();    // get graphics object to draw on created image.
    }
    public void start()
    {
        t.start();
    }
    public void run()
    {
        while(true)
        {
            x = (x+1)%360;     // gradually increase length of arc angle up to 360 degree
            if(x == 0)       
       /* when x reached to 0 that means completed 360 degree angle and now need to change the current and next image 
          index.  */ 
            {
                pre = (pre+1)%Image_List.length;
                next = (next+1)%Image_List.length;
            }
            repaint();   //make calls to update.
            try
            {
                Thread.sleep(10);
            }
            catch(Exception ex)
            {
                System.out.println(ex);
            }
        }
    }
    public void update(Graphics g)
    {
        paint(g);
    }
    public void paint(Graphics g)
    {
/* we need to create two texture paints paint 1 and paint2, first one will make use of current image and second one make
 use of next image. Then use paint one and fill an oval on image img, and use paint2 to fill an arc on the same image img.
 And finally draw the image img on Applet window.  */
        Graphics2D gd = (Graphics2D)gimg;   
        BufferedImage bi1 = new BufferedImage(aw, ah, 1);
        Graphics gbi1 = bi1.getGraphics();
        Image img1 = getImage(getCodeBase(),Image_List[pre]);
        gbi1.drawImage(img1, 0, 0, aw, ah, this);
        Rectangle2D r1 = new Rectangle2D.Double(0, 0, aw, ah);
        TexturePaint paint1 = new TexturePaint(bi1, r1);
        BufferedImage bi2 = new BufferedImage(aw, ah, 1);
        Graphics gbi2 = bi2.getGraphics();
        Image img2 = getImage(getCodeBase(),Image_List[next]);
        gbi2.drawImage(img2, 0, 0, aw, ah, this);
        Rectangle2D r2 = new Rectangle2D.Double(0, 0, aw, ah);
        TexturePaint paint2 = new TexturePaint(bi2, r2);
        gd.setPaint(paint1);
        gd.fillOval(0, 0, aw, ah);
        gd.setPaint(paint2);
        gd.fillArc(0, 0, aw, ah, 0, x);
        g.drawImage(img, 0, 0, this);

    }
}

Output -

Animation 3 -

Animated Flag-
import java.awt.*;
import java.applet.*;
import java.awt.geom.*;
import java.awt.image.BufferedImage;
public class Test extends Applet implements Runnable
{
    int c = 0;
    Thread t;
    public void init()
    {
      t = new Thread(this);
    }
    public void start()
    {
        t.start();
    }
    public void run()
    {
        while(true)
        {
            c = (c+1)%70;
            repaint();
            try
            {
                Thread.sleep(20);
            }
            catch(Exception ex)
            {
                System.out.println(ex);
            }
        }
    }

    public void paint(Graphics g)
    {
        Graphics2D gd = (Graphics2D)g;
        gd.fillRect(120, 250, 160, 10);
        gd.drawRect(140, 240, 120, 10);
        gd.fillRect(160, 230, 80, 10);
        gd.fillRect(195, 20, 10, 210);
        GeneralPath p1 = new GeneralPath();
        GeneralPath p2 = new GeneralPath();
        GeneralPath p3 = new GeneralPath();
        p1.moveTo(205, 30);
        p1.curveTo(205+c, -30, 235+c, 60, 290, 30);
        p1.lineTo(290, 50);
        p1.curveTo(235+c, 80, 205+c, -10, 205, 50);
        p1.lineTo(205, 70);
        gd.setColor(Color.ORANGE);
        gd.fill(p1);
        p2.moveTo(205, 50);
        p2.curveTo(205+c, -10, 235+c, 80, 290, 50);
        p2.lineTo(290, 70);
        p2.curveTo(235+c, 100, 205+c, 10, 205, 70);
        p2.lineTo(205, 50);
        gd.setColor(Color.WHITE);
        gd.fill(p2);
        p3.moveTo(205, 70);
        p3.curveTo(205+c, 10, 235+c, 100, 290, 70);
        p3.lineTo(290, 90);
        p3.curveTo(235+c, 120, 205+c, 30, 205, 90);
        p3.lineTo(205, 70);
        gd.setColor(Color.GREEN);
        gd.fill(p3);

    }
}    

Output -