import java.awt.*;
import java.applet.*;
public class Test extends Applet implements Runnable {
int nr = 0;
Thread thread;
Dimension d;
public void init() {
d = size();
}
public void run() {
long starttime;
Graphics g;
g=getGraphics();
Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
while(true) {
starttime=System.currentTimeMillis();
try {
paint(g);
starttime += 30;
nr++;
Thread.sleep(Math.max(0, starttime-System.currentTimeMillis()));
}
catch (InterruptedException e) {
break;
}
}
}
public void start() {
if (thread == null) {
thread = new Thread(this);
thread.start();
}
}
public void stop() {
if (thread != null) {
thread.stop();
thread = null;
}
}
public void paint(Graphics g)
{
g.setColor(Color.WHITE);
g.fillRect(0,0,d.width,d.height);
g.setColor(Color.MAGENTA);
g.drawString(nr, 10, 10);
}
}
[java] How do you repaint graphics in applet?
You need to setup a backbuffer as a BufferedImage which is the same size as the applet and draw to that first. Then on a TIMED interval draw to the applet.
You can setup the back buffer with the following couple of lines of code
//add this as a class variable
private BufferedImage bkbuffer = null;
Then in the init() method you want to create the BufferedImage after getting the size.
bkbuffer = new BufferedImage( d.getWidth(), d.getHeight(), BufferedImage.TYPE_INT_ARGB );
Then in your run() method change
g=getGraphics();
to
g = bkbuffer.getGraphics();
Then after the paint(g) line add the following
getGraphics().drawImage(bkbuffer,0,0,null);
That should reduce flickering if not eliminate flickering.
One additional thing and that is you do not want to be changing the priority of the thread. You might have done this to try and reduce the flickering so I advise removing it. You do not need to be sleeping but instead look into using TimerTask it is much more efficient and intuitive.
You can setup the back buffer with the following couple of lines of code
//add this as a class variable
private BufferedImage bkbuffer = null;
Then in the init() method you want to create the BufferedImage after getting the size.
bkbuffer = new BufferedImage( d.getWidth(), d.getHeight(), BufferedImage.TYPE_INT_ARGB );
Then in your run() method change
g=getGraphics();
to
g = bkbuffer.getGraphics();
Then after the paint(g) line add the following
getGraphics().drawImage(bkbuffer,0,0,null);
That should reduce flickering if not eliminate flickering.
One additional thing and that is you do not want to be changing the priority of the thread. You might have done this to try and reduce the flickering so I advise removing it. You do not need to be sleeping but instead look into using TimerTask it is much more efficient and intuitive.
Alternatively, you could extend JApplet instead of Applet which iirc automatically provides double buffering.
Yes, use JApplet.
Second, use the kosher way of implementing custom drawing:
Next, update only in Swing's event loop, by calling repaint on your applet.
So in the end, you have something like this:
Also - never mess with thread priority.
Second, use the kosher way of implementing custom drawing:
public void paintComponent(Graphics g){ super.paintComponent(g); // optional}
Next, update only in Swing's event loop, by calling repaint on your applet.
So in the end, you have something like this:
public class Test extends JApplet{ public void run() { try { long time = System.currentTimeMillis(); while (running) { long curr = System.currentTimeMillis(); long delta = curr-time; time = curr; // update the logic ... doLogicStuff( delta ); repaint(); Thread.sleep( 1 ); } } catch (Exception e) { e.printStackTrace(); } } public void paintComponent(Graphics g){ // draw the stuff } }
Also - never mess with thread priority.
import java.awt.*;import javax.swing.*;public class Test extends JApplet implements Runnable { int nr = 0; public void run() { while (true) { try { nr++; repaint(); Thread.sleep(20); } catch (Exception e) { e.printStackTrace(); } } } public void paint(Graphics g){ g.setColor(Color.MAGENTA); g.drawString("-"+nr, 10, 10); }}
Why it's not working?
Here is an implementation that I have observed absolutely no flickering with.
Try this and let me know if flickering occurs at all.
import java.awt.Color;import java.awt.Graphics;import java.awt.image.BufferedImage;import java.util.Timer;import java.util.TimerTask;import javax.swing.JApplet;public class Test extends JApplet { private int nr = 0; private BufferedImage bkbuffer = null; private Timer tasker = new Timer(); public void init() { this.setIgnoreRepaint(true); bkbuffer = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB); TimerTask t = new TimerTask() { public void run() { Graphics g; //g=getGraphics(); g = bkbuffer.getGraphics(); paint(g); nr++; getGraphics().drawImage(bkbuffer, 0, 0, null); } }; //render every 16 milliseconds tasker.schedule(t, 100, 16); } public void paint(Graphics g) { g.setColor(Color.WHITE); g.fillRect(0, 0, getWidth(), getHeight()); g.setColor(Color.MAGENTA); g.drawString(" " + nr, 40, 40); }}
Try this and let me know if flickering occurs at all.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement