Skip to main content
GameDev.net gamedev.net
🔒 Locked 🎮 Unity

[java] How do you repaint graphics in applet?

Started by Himent Aug 3, 2007 at 10:47 AM 10 replies 2.1k views
Original Post
Himent
Himent
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);
    }
}

My applet is blinking. How do I make it to do not blink? [Edited by - Himent on August 3, 2007 12:07:15 PM]
5MinuteGaming
5MinuteGaming
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.
Luctus
Luctus
Alternatively, you could extend JApplet instead of Applet which iirc automatically provides double buffering.
-LuctusIn the beginning the Universe was created. This has made a lot of people very angry and been widely regarded as a bad move - Douglas Adams
Antheus
Antheus
Yes, use JApplet.

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.
Himent
Himent
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?
Antheus
Antheus
Try paintComponent, not paint.
Himent
Himent
Quote:
Original post by Antheus
Try paintComponent, not paint.


It doesn't call run() method...
5MinuteGaming
5MinuteGaming
Here is an implementation that I have observed absolutely no flickering with.

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.
Himent
Himent
Quote:
Original post by 5MinuteGaming
Here is an implementation that I have observed absolutely no flickering with.

*** Source Snippet Removed ***
Try this and let me know if flickering occurs at all.


Thanks, it's not flickering!
Himent
Himent
import java.awt.Color;import java.awt.Graphics;import java.awt.image.BufferedImage;import java.util.Timer;import java.util.TimerTask;import java.net.*;import java.io.*;import javax.swing.JApplet;public class Test extends JApplet {	private DatagramSocket socket;		private BufferedImage bkbuffer = null;	private Timer tasker = new Timer();		/*private Timer noPacket = new Timer();*/		private String received = "Connecting...";		/*private TimerTask noPacketR = new TimerTask() {		public void run() {			Graphics g = bkbuffer.getGraphics();			received = "Connection lost";			paint(g);			socket.close();		}	};*/		public void sendAndReceive() throws IOException {	        byte[] buf = new byte[256];	        InetAddress address = InetAddress.getByName("localhost");	        DatagramPacket packet = new DatagramPacket(buf, buf.length, address, 4445);	        socket.send(packet);	        packet = new DatagramPacket(buf, buf.length);	        socket.receive(packet);	        received = new String(packet.getData(), 0, packet.getLength());	}		public void init() {			this.setIgnoreRepaint(true);				bkbuffer = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);				TimerTask t = new TimerTask() {			public void run() {				Graphics g = bkbuffer.getGraphics();							try {					sendAndReceive();				} catch (IOException e) {}							paint(g);								getGraphics().drawImage(bkbuffer, 0, 0, null);							}		};		//render every 20 milliseconds		tasker.schedule(t, 100, 20);	}	public void paint(Graphics g) {		g.setColor(Color.WHITE);		g.fillRect(0, 0, getWidth(), getHeight());		g.drawString(received,10,10);	}}


When I run this I get error:
Quote:
Exception in thread "Timer-0" java.lang.NullPointerException
at Test.sendAndReceive(Test.java:36)
at Test$1.run(Test.java:53)
at java.util.TimerThread.mainLoop(Timer.java:512)
at java.util.TimerThread.run(Timer.java:462)


What's wrong now??

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.