Sign in to follow this  
Himent

[java] How do you repaint graphics in applet?

Recommended Posts

Himent    134
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]

Share this post


Link to post
Share on other sites
5MinuteGaming    274
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.

Share this post


Link to post
Share on other sites
Antheus    2409
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.

Share this post


Link to post
Share on other sites
Himent    134
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?

Share this post


Link to post
Share on other sites
5MinuteGaming    274
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.

Share this post


Link to post
Share on other sites
Himent    134
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!

Share this post


Link to post
Share on other sites
Himent    134

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??

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this