Double buffering

I am new to java and am trying to turn some of my C++ game projects into java applets. My double buffering is not working, I am getting a lot of flicker when I try to scroll the background. Can someone please tell me what I am doing wrong? I don’t see how I am getting flicker since the map is being drawn to the buffer image, then to the screen.


public void init( ) {
    tile[SKY] = getImage(getDocumentBase(), "sky.png");
    tile[CLOUD_1] = getImage(getDocumentBase(), "cloud_1.png");
    tile[CLOUD_2] = getImage(getDocumentBase(), "cloud_2.png");
    tile[RED_BRICKS] = getImage(getDocumentBase(), "red_bricks.png");
    buffer = createImage(APPLET_WIDTH, APPLET_HEIGHT);
    bufferg = buffer.getGraphics();
    addKeyListener(this);
  }
  
  public void paint(Graphics g) { 
    
    if(buffer != null) {
      int tile_id;
      for(int y=0;y<MAP_ROWS;y++) {
        for(int x=0;x<MAP_COLS;x++) {
          tile_id = map[y][x]; 
          bufferg.drawImage(tile[tile_id], x * TILE_SIZE, y * TILE_SIZE, this);
        }
      }
    }
 
    g.drawImage(buffer, screenX, screenY, this); 
  }

The way I always do DoubleBuffering is overriding update(); Here’s how I do it:

private Image dbImage;
private Graphics dbg;
public void update(Graphics g)
{
	if(dbImage == null)
	{
		dbImage = createImage(this.getSize().width, this.getSize().height);
		dbg = dbImage.getGraphics();
	}
	dbg.setColor (getBackground ());
	dbg.fillRect (0, 0, this.getSize().width, this.getSize().height);
	dbg.setColor (getForeground());
	paint (dbg);

	g.drawImage (dbImage, 0, 0, this); 
}

Now do I need to call update() explicitly? Or is it called automatically?

Right now, I am calling repaint() if certain keys are being pressed. Based on which keys are pressed I am either incrementing/decrementing from my maps world screen coordinates.

Would updating the buffer inside paint() cause the applet window to flicker?

Erick

update() is called automatically. I know it’s called in repaint(), but it might be called automatically in paint() to.

Nice, I got it to double buffer correctly, thanks for the information.

Erick

update() is called automatically. Then update() clears the screen and calls paint(). The flicker comes from update() clearing the screen. So add the following code:


public void update(Graphics g) {
  // overrides update to prevent clearing of the screen
  paint(g);
}

is it possible to do double buffering on a JPanel?

Here’s a great article describing double buffering

http://www.developer.com/tech/article.php/626541

ENC, JPanels are double buffered by Swing. You can set a BufferStrategy for the panel’s ancestral JFrame and do active rendering, but this implies that all the panels of the JFrame use that BufferStrategy. My solution is to use a java.awt.Canvas which can have its own BufferStrategy completely independent of other components. Then you have good control of the rendering process on the Canvas without having to worry about any other components.

However there are texts which advise against using AWT components since they are ‘heavyweight’ . Not that I have had performance problems with this.