I’m sure you recognized in the first applet that
the cirlce is flickering. There is a very simple reason for this.
Every time the paint – method is called by repaint() the applet screen
is cleared completely. Because of this we can see for a millisecond a
absolutely blank screen. To suppress this phenomena, we have three
possibilities:

  1. We don’t clear the screen at all
  2. We clear the screen only where something is changing
  3. We use double buffering

Don’t clear the screen at all

This
idea seems to be the solution to all our problems (but it is not!). In
our case it would mean that the ball would paint a thick red line
across the applet because the screen stays red at every position the
ball has been once. This might be ok for some situations but we want to
see a moving ball, not a thick red line. So this technique is just
useful for objects that are not moving.
At first it is important
for you to know one thing. The call of repaint() doesn’t call the
paint() – method at the same time. Instead a method called update() is
called. If one doesn’t overwrite this method, update() clears the
complete screen and afterward calls paint() which paints the
background and our circle again. To avoid clearing the screen you have
to overwrite the update() – method. Our new update() – method doesn’t
clear the screen anymore, but just calls paint(). This can be done with
three line of code:

public void update(Graphics g)
{

    paint(g);

}

As I said before this is no solution for our applet.
But it is essential to understand that repaint() doesn’t call paint()
but update() which calls paint() then!!

Clear the screen only where something is changing

This solution is based on the idea to repaint just
these parts of our applet where something has changed. This concept is
very good for a game like snakin’. If the last part of your snake is
colored in the same color as the background, this part overpaints the
parts of the snake, where the snake has been. I don’t want to talk
about this solution in detail, because one could use this method just
in very special situations. So let’s talk about the double buffering
which is a really good and effective solution to avoid a flickering
screen and the best of it all: You can use this method in every applet
the same way as I do now, so you’ll never have to worry about that
problem again!

Double buffering

As I said you can use double buffering in every
applet in a very easy way. Double buffering means to paint all the
things in the paint() method to a offscreen image. If all things, that
have to be painted, are painted, this image is copied to the applet
screen. The method does the following in detail:

  1. Generate a new offscreen-image by using createImage and store this image in a instance variable( = generate a empty image)
  2. Call getGraphics to get graphic context for this image
  3. Draw everything (including to clear the screen complete) on the offscreen image ( = draw image in the background)
  4. When finished, copy this image over the existing image on the screen. ( = draw image in the foreground)

This technique means that the picture is already
painted before it is copied to the screen. When coping the image to
the foreground the old pixels are overlaid by the new ones. There
won’t be any flickering picture anymore because there is not a
millisecond you could see a empty screen!

The only disadvantage of the double buffering is,
that it produces a large amount of data and every image is drawn two
times (offscreen and when coping to the screen). But in most cases and
on a fast computer this is much better than wasting time on finding an
other solution!

Well after all this theory I will show you how to
integrate the double buffering into our “ball moving” applet :

Double buffering: the code

// declare two instance variables at the head of the program
private Image dbImage;
private Graphics dbg;

… other code …

/** Update – Method, implements double buffering */
public void update (Graphics g)
{

    // initialize buffer
    if (dbImage == null)
    {

      dbImage = createImage (this.getSize().width, this.getSize().height);
      dbg = dbImage.getGraphics ();

    }

    // clear screen in background
    dbg.setColor (getBackground ());
    dbg.fillRect (0, 0, this.getSize().width, this.getSize().height);

    // draw elements in background
    dbg.setColor (getForeground());
    paint (dbg);

    // draw image on the screen
    g.drawImage (dbImage, 0, 0, this);

}

As I said before you can copy and paste this code into every applet that uses animations!