user3495474
user3495474

Reputation: 1

Double Buffering in Java using BufferedImage dosn't show image

I'm trying to double buffer my screen in a run() method using BufferedImage. It doesn't show the image (although it does show other graphics paintings done by g.drawRect etc.). I'm trying to implement active rendering, so my painting is not in paintComponent, but in my own method. When I put it in the paintComponent it does work.... Anyone knows what seem to be the problem?

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.swing.JPanel;


public class GamePanel extends JPanel implements Runnable
{
private static final int PWIDTH = 500, PHEIGHT = 500, PERIOD = 40;
private Image bgImage;
private BufferedImage dbImg = null;
private boolean running; 

public GamePanel()
{
    bgImage = Toolkit.getDefaultToolkit().getImage((new File(".")).getAbsolutePath() + "//a.jpg");

}

public void run()
{

    long before, diff, sleepTime;
    before = System.currentTimeMillis();
    running = true;
    int x = 1;
    while(x <= 5)
    {
        gameRender();
        paintScreen();   // active rendering

        try {
            Thread.sleep(50);
        }
        catch(InterruptedException e){}

        x++;
    }

}

// only start the animation once the JPanel has been added to the JFrame
public void addNotify()
{ 
    super.addNotify();   // creates the peer
    startGame();    // start the thread
}
public void startGame()
{
    (new Thread(this)).start();
}
public void gameRender()
{
    Graphics dbg;

    dbImg = new BufferedImage(PWIDTH, PHEIGHT, BufferedImage.TYPE_INT_ARGB);
  //  dbImg = (BufferedImage)createImage(PWIDTH, PHEIGHT);
    dbg = dbImg.getGraphics();
    dbg.setColor(Color.GREEN);
    dbg.fillRect(0, 0, PWIDTH, PHEIGHT);
    dbg.drawImage(bgImage, 0, 0, null); // doesn't show

    dbg.setColor(Color.ORANGE);  // this one shows
    dbg.fillRect(100, 100, 100, 100);

}
public void paintScreen()
{
    Graphics g;
    try {
        g = getGraphics();
        if(g != null && dbImg != null)
        {
            g.drawImage(dbImg, 0, 0, null);
        }
    }
    catch(Exception e)
    {
        System.out.println("Graphics error");
        e.printStackTrace();
    }
}

}

Upvotes: 0

Views: 372

Answers (1)

MadProgrammer
MadProgrammer

Reputation: 347334

getGraphics is not how custom painting is done, see Performing a Custom Painting for more details

You should consider having a active and passive buffer. The active buffer is what should be painted to the screen and the passive buffer should be what is been updated. This would insure you don't end up with a dirty update, that is a partial update to the buffer been painted to the screen.

Once the update is complete, you would swap the buffers and request a repaint. To make it safer, when swapping the buffers and painting the should be do be within a synchronized block

Having said all that, Swing components are double buffered by default

Upvotes: 3

Related Questions