There are two ways to solve this problem. The simplest solution is a clipping region. A clipping region is a rectangular area inside of which you can draw and outside of which you can't. By setting the clipping region you limit the area which is drawn into. This means first of all that nothing outside that region flickers. Secondly the smaller area can be drawn more quickly so there's less likelihood of flicker.
To set a clipping rectangle call g.clipRect(Rect r)
inside your paint()
method where r
is the rectangle you want to clip to. The bounce applet is perfect for this since you have a convenient rectangle to which to clip. Here's a revised ClipBounce applet
that clips the region to be drawn.
import java.awt.*;
import java.applet.*;
import java.util.*;
public class ClipBounce extends Applet implements Runnable {
Rectangle r;
int x_increment = 1;
int deltaY = 1;
int speed = 30;
public void init () {
r = new Rectangle(37, 17, 20, 20);
Thread t = new Thread(this);
t.start();
}
public void paint (Graphics g) {
g.setColor(Color.red);
g.clipRect(r.x, r.y, r.width, r.height);
g.fillOval(r.x, r.y, r.width, r.height);
}
public void run() {
while (true) { // infinite loop
long t1 = (new Date()).getTime();
r.x += deltaX;
r.y += deltaY;
if (r.x >= size().width || r.x < 0) deltaX *= -1;
if (r.y >= size().height || r.y < 0) deltaY *= -1;
this.repaint();
long t2 = (new Date()).getTime();
try {
Thread.sleep(speed - (t2 - t1));
}
catch (InterruptedException ie) {
}
}
}
}