Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How to avoid flicker? (tried double-buffering) 1

Status
Not open for further replies.

imp

Programmer
Jul 24, 2000
9
US
<b>I made the below application to see if I could implement double-buffering to<br>avoid flicker during animation.&nbsp;&nbsp;I did the double-buffering, but I'm still<br>getting flicker.&nbsp;&nbsp;It appears to be caused by the MyFrame.paint () method<br>painting the Frame background before displaying the off-screen image.&nbsp;&nbsp;(I made<br>the background color red to verify this was the issue.)&nbsp;&nbsp;What am I doing wrong?<br>Should I be using Panel instead of Frame or something like that?&nbsp;&nbsp;Suggestions,<br>ideas, etc. would be greatly appreciated.&nbsp;&nbsp;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>&nbsp;&nbsp;bgColor = new Color ( 60,&nbsp;&nbsp;60, 60);<br>&nbsp;&nbsp;obColor = new Color (255, 255,&nbsp;&nbsp;0);<br>&nbsp;&nbsp;f = new MyFrame (256, 256);<br>&nbsp;&nbsp;hidden = f.getImage (); // f.createImage (256, 256);<br>&nbsp;&nbsp;hiddenG = hidden.getGraphics ();<br>&nbsp;&nbsp;posX = 128;<br>&nbsp;&nbsp;posY = 128;<br>&nbsp;&nbsp;minX = radius;<br>&nbsp;&nbsp;minY = radius;<br>&nbsp;&nbsp;maxX = 256 - radius;<br>&nbsp;&nbsp;maxY = 256 - radius;<br>&nbsp;&nbsp;rndOb = new java.util.Random (System.currentTimeMillis ());<br>&nbsp;&nbsp;velX = rndOb.nextFloat () * 20;<br>&nbsp;&nbsp;velY = rndOb.nextFloat () * 20;<br>&nbsp;&nbsp;diameter = radius * 2;<br>&nbsp;&nbsp;delay = 50;<br>&nbsp;&nbsp;velLoss = (float)0.9;<br>&nbsp;&nbsp;start ();<br>} // =------------------------------------------------------=[CONSTRUCTOR: END ]<br><br>void updateHidden ()<br>{ // =-----------------------------------------------------=[updateHidden:BEGIN]<br>&nbsp;&nbsp;int radius = diameter / 2;<br>&nbsp;&nbsp;hiddenG.setColor (bgColor);<br>&nbsp;&nbsp;hiddenG.fillRect (0, 0, 256, 256);<br>&nbsp;&nbsp;hiddenG.setColor (obColor);<br>&nbsp;&nbsp;hiddenG.drawOval (posX - radius, posY - radius, diameter, diameter);<br>} // =-----------------------------------------------------=[updateHidden: END ]<br><br>void bounceBall ()<br>{ // =-------------------------------------------------------=[bounceBall:BEGIN]<br>&nbsp;&nbsp;float newPosX = posX + velX;<br>&nbsp;&nbsp;float newPosY = posY + velY;<br>&nbsp;&nbsp;if ((newPosX &lt; minX) ¦ (newPosX &gt; maxX) ¦<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(newPosY &lt; minY) ¦ (newPosY &gt; maxY))<br>&nbsp;&nbsp;&nbsp;{ velX = velX * velLoss;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;velY = velY * velLoss;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ((velX &gt; -1.0) & (velX &lt; 1.0)) velX = (float)0.0;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ((velY &gt; -1.0) & (velY &lt; 1.0)) velY = (float)0.0;<br>&nbsp;&nbsp;&nbsp;//System.out.println (&quot;velocity = (&quot; + velX + &quot;, &quot; + velY + &quot;).&quot;);<br>&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;if ((newPosX &lt; minX) ¦ (newPosX &gt; maxX))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ velX = -velX;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (newPosX &lt; minX)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;newPosX = newPosX + (minX - newPosX);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else newPosX = newPosX - (newPosX - maxX);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;if ((newPosY &lt; minY) ¦ (newPosY &gt; maxY))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ velY = -velY;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (newPosY &lt; minY)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;newPosY = newPosY + (minY - newPosY);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else newPosY = newPosY - (newPosY - maxY);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;posX = (int)newPosX;<br>&nbsp;&nbsp;posY = (int)newPosY;<br>//System.out.println (&quot;New pos = (&quot; + posX + &quot;, &quot; + posY + &quot;).&quot;);<br>} // =-------------------------------------------------------=[bounceBall: END ]<br><br>public void run ()<br>{ // =--------------------------------------------------------------=[run:BEGIN]<br>&nbsp;&nbsp;long targetTime;<br>&nbsp;&nbsp;while (true)<br>&nbsp;&nbsp;{ targetTime = System.currentTimeMillis () + delay;<br>&nbsp;&nbsp;&nbsp;&nbsp;bounceBall ();<br>&nbsp;&nbsp;&nbsp;&nbsp;updateHidden ();<br>&nbsp;&nbsp;&nbsp;&nbsp;f.repaint ();&nbsp;&nbsp;// f.update (f.getGraphics ());<br>&nbsp;&nbsp;&nbsp;&nbsp;if ((velX != 0.0) && (velY != 0.0))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ targetTime = targetTime - System.currentTimeMillis ();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (targetTime &lt; 1) targetTime = 1;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//System.out.println (&quot;Sleeping for &quot; + targetTime + &quot; milli-seconds.&quot;);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;try { sleep (targetTime); }<br>&nbsp;&nbsp;&nbsp;&nbsp;catch (InterruptedException e)<br>&nbsp;&nbsp;&nbsp;&nbsp;{ System.out.println (e.toString ());<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.exit (0);<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;}<br>} // =--------------------------------------------------------------=[run: END ]<br><br>public static void main (String [] args)&nbsp;&nbsp;{ Anim1 a = new Anim1 (16); }<br><br>class MyFrame extends Frame<br>{ // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=[MyFrame :BEGIN]<br>static final int MARGINWIDTH&nbsp;&nbsp;=&nbsp;&nbsp;4;<br>static final int MARGINHEIGHT =&nbsp;&nbsp;4;<br>static final int TITLEHEIGHT&nbsp;&nbsp;= 19;<br>Image hidden;<br><br>MyFrame (int sizeX, int sizeY)<br>{ // =------------------------------------------------------=[CONSTRUCTOR:BEGIN]<br>&nbsp;&nbsp;super ();<br>&nbsp;&nbsp;setTitle (&quot;Anim1&quot;);<br>&nbsp;&nbsp;setBackground (new Color (255, 0, 0)); // Shouldn't show.<br>&nbsp;&nbsp;setSize (sizeX + MARGINWIDTH * 2, sizeY + MARGINHEIGHT * 2 + TITLEHEIGHT);<br>&nbsp;&nbsp;addWindowListener (new AppCloser ());<br>&nbsp;&nbsp;this.show ();<br>&nbsp;&nbsp;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>&nbsp;&nbsp;if (hidden != null)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;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>
 
Dear imp,<br><br>Try overriding the Component.update() method and have it call paint(). The default handler repaints the entire canvas with the current background color, then calls paint(), so to avoid that flicker just call paint() i.e.,:<br><br>public void update(Graphics g){<br>&nbsp;&nbsp;paint(g);<br>}<br><br>Hope this helps<br>-pete
 
paint and repaint were in a boat... paint fell out- who was left?<br><br><br>hehehehehehehehehehehe sorry about that... ok, I'm done. From a theoretical standpoint, might repaint be better? <p>Liam Morley<br><a href=mailto:lmorley@wpi.edu>lmorley@wpi.edu</a><br><a href=] :: imotic :: website :: [</a><br>"light the deep, and bring silence to the world.<br>
light the world, and bring depth to the silence.
 
<b>Excellent! Groovy! That did the trick!</b><br>So palbano, is there some book, web site, guru, or other source of important-but-not-obvious information such as &quot;<FONT FACE=monospace><font color=blue>Component.update ()</font></font> paints the background color before calling <FONT FACE=monospace><font color=blue>paint (g)</font></font>&quot;, or are you just very familiar with the source code of the standard Java classes?<br>And imotic, what were your reasons for saying I might want to override <FONT FACE=monospace><font color=blue>repaint ()</font></font> instead of <FONT FACE=monospace><font color=blue>update ()</font></font>?<br><i>(Thanks again guys!)</i>
 
Dear imp,<br><br>I started out with your basic 'Core Java' book from Sun (first edition), ouch that's a long time ago. It's now in it's second edition and has two volumns. I would highly recommend those volumns for all Java Novices. <br><br>&quot;But, that's just my opinion... I could be wrong&quot;.<br>-pete
 
well the thought is you're supposed to call paint the first time and then repaint each additional time (not unlike some phone plans)... so something like<br>public void update(Graphics g){<br>&nbsp;&nbsp;paint(g);<br>}<br><br>might theoretically be better as<br>public void update(Graphics g){<br>&nbsp;&nbsp;repaint(g);<br>}<br><br>or just<br>public void update(Graphics g){<br>&nbsp;&nbsp;repaint();<br>}<br><br><br>to tell you the truth, I don't even remember if the repaint() needs an argument, or whether either will work.. I don't work with applets all that often. But I've always thought that paint gets called the first time by the browser, and repaint gets called each additional time.. doesn't really matter, though, I suppose.<br> <p>Liam Morley<br><a href=mailto:lmorley@wpi.edu>lmorley@wpi.edu</a><br><a href=] :: imotic :: website :: [</a><br>"light the deep, and bring silence to the world.<br>
light the world, and bring depth to the silence.
 
Dear Liam,<br><br>You posted this:<br><br>*******<br>might theoretically be better as<br>public void update(Graphics g){<br>&nbsp;&nbsp;repaint(g);<br>}<br><br>or just<br>public void update(Graphics g){<br>&nbsp;&nbsp;repaint();<br>}<br>********<br><br>Ouch, that should hurt! i.e., the following from the JDK<br>-----------------------<br>public void repaint()<br><br>Repaints this component. <br>This method causes a call to this component's update method as soon as possible.<br><br>See Also:<br>update<br><br>Since:<br>JDK1.0 <br><br>------------------------<br><br>So... calling repaint() from update() should cause an infinite loop probably resulting in a stack overflow in a correctly implemented VM. I'll let you test it out. ;o)<br><br>-pete
 
hehehe :eek:) no, you can have the honors.. I told you, I don't do much applet/graphic stuff in Java, I'm more applications-based :eek:) that will change if I can convince my admins to run servlets, which I might just be able to do.. <p>Liam Morley<br><a href=mailto:lmorley@wpi.edu>lmorley@wpi.edu</a><br><a href=] :: imotic :: website :: [</a><br>"light the deep, and bring silence to the world.<br>
light the world, and bring depth to the silence.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top