<b>I made the below application to see if I could implement double-buffering to<br>avoid flicker during animation. I did the double-buffering, but I'm still<br>getting flicker. It appears to be caused by the MyFrame.paint () method<br>painting the Frame background before displaying the off-screen image. (I made<br>the background color red to verify this was the issue.) What am I doing wrong?<br>Should I be using Panel instead of Frame or something like that? Suggestions,<br>ideas, etc. would be greatly appreciated. Thanks.<br>________________________________________________________________________________</b><br><br><FONT FACE=monospace>import java.awt.*;<br>import java.awt.event.*;<br>class Anim1 extends Thread implements Runnable<br>{ // ==============================================================[Anim1:BEGIN]<br>Color bgColor;<br>Color obColor;<br>MyFrame f;<br>Image hidden;<br>Graphics hiddenG;<br>int minX;<br>int maxX;<br>int minY;<br>int maxY;<br>int posX;<br>int posY;<br>float velX;<br>float velY;<br>int diameter;<br>int delay;<br>float velLoss;<br>java.util.Random rndOb;<br><br>Anim1 (int radius)<br>{ // =------------------------------------------------------=[CONSTRUCTOR:BEGIN]<br> bgColor = new Color ( 60, 60, 60);<br> obColor = new Color (255, 255, 0);<br> f = new MyFrame (256, 256);<br> hidden = f.getImage (); // f.createImage (256, 256);<br> hiddenG = hidden.getGraphics ();<br> posX = 128;<br> posY = 128;<br> minX = radius;<br> minY = radius;<br> maxX = 256 - radius;<br> maxY = 256 - radius;<br> rndOb = new java.util.Random (System.currentTimeMillis ());<br> velX = rndOb.nextFloat () * 20;<br> velY = rndOb.nextFloat () * 20;<br> diameter = radius * 2;<br> delay = 50;<br> velLoss = (float)0.9;<br> start ();<br>} // =------------------------------------------------------=[CONSTRUCTOR: END ]<br><br>void updateHidden ()<br>{ // =-----------------------------------------------------=[updateHidden:BEGIN]<br> int radius = diameter / 2;<br> hiddenG.setColor (bgColor);<br> hiddenG.fillRect (0, 0, 256, 256);<br> hiddenG.setColor (obColor);<br> hiddenG.drawOval (posX - radius, posY - radius, diameter, diameter);<br>} // =-----------------------------------------------------=[updateHidden: END ]<br><br>void bounceBall ()<br>{ // =-------------------------------------------------------=[bounceBall:BEGIN]<br> float newPosX = posX + velX;<br> float newPosY = posY + velY;<br> if ((newPosX < minX) ¦ (newPosX > maxX) ¦<br> (newPosY < minY) ¦ (newPosY > maxY))<br> { velX = velX * velLoss;<br> velY = velY * velLoss;<br> if ((velX > -1.0) & (velX < 1.0)) velX = (float)0.0;<br> if ((velY > -1.0) & (velY < 1.0)) velY = (float)0.0;<br> //System.out.println ("velocity = (" + velX + ", " + velY + "."<br> }<br> if ((newPosX < minX) ¦ (newPosX > maxX))<br> { velX = -velX;<br> if (newPosX < minX)<br> newPosX = newPosX + (minX - newPosX);<br> else newPosX = newPosX - (newPosX - maxX);<br> }<br> if ((newPosY < minY) ¦ (newPosY > maxY))<br> { velY = -velY;<br> if (newPosY < minY)<br> newPosY = newPosY + (minY - newPosY);<br> else newPosY = newPosY - (newPosY - maxY);<br> }<br> posX = (int)newPosX;<br> posY = (int)newPosY;<br>//System.out.println ("New pos = (" + posX + ", " + posY + "."<br>} // =-------------------------------------------------------=[bounceBall: END ]<br><br>public void run ()<br>{ // =--------------------------------------------------------------=[run:BEGIN]<br> long targetTime;<br> while (true)<br> { targetTime = System.currentTimeMillis () + delay;<br> bounceBall ();<br> updateHidden ();<br> f.repaint (); // f.update (f.getGraphics ());<br> if ((velX != 0.0) && (velY != 0.0))<br> { targetTime = targetTime - System.currentTimeMillis ();<br> if (targetTime < 1) targetTime = 1;<br> //System.out.println ("Sleeping for " + targetTime + " milli-seconds."<br> }<br> try { sleep (targetTime); }<br> catch (InterruptedException e)<br> { System.out.println (e.toString ());<br> System.exit (0);<br> }<br> }<br>} // =--------------------------------------------------------------=[run: END ]<br><br>public static void main (String [] args) { Anim1 a = new Anim1 (16); }<br><br>class MyFrame extends Frame<br>{ // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=[MyFrame :BEGIN]<br>static final int MARGINWIDTH = 4;<br>static final int MARGINHEIGHT = 4;<br>static final int TITLEHEIGHT = 19;<br>Image hidden;<br><br>MyFrame (int sizeX, int sizeY)<br>{ // =------------------------------------------------------=[CONSTRUCTOR:BEGIN]<br> super ();<br> setTitle ("Anim1"<br> setBackground (new Color (255, 0, 0)); // Shouldn't show.<br> setSize (sizeX + MARGINWIDTH * 2, sizeY + MARGINHEIGHT * 2 + TITLEHEIGHT);<br> addWindowListener (new AppCloser ());<br> this.show ();<br> hidden = createImage (256, 256);<br>} // =------------------------------------------------------=[CONSTRUCTOR: END ]<br><br>public Image getImage () { return hidden; }<br><br>public void paint (Graphics g)<br>{ // =------------------------------------------------------------=[paint:BEGIN]<br> if (hidden != null)<br> g.drawImage (hidden, MARGINWIDTH, MARGINHEIGHT + TITLEHEIGHT, this);<br>} // =------------------------------------------------------------=[paint: END ]<br><br>} // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=[MyFrame : END ]<br><br>protected static final class AppCloser extends WindowAdapter<br>{ public void windowClosing (WindowEvent e) { System.exit (0); } }<br><br>} // ==============================================================[Anim1: END ]</font>