Drareeg
Drareeg

Reputation: 99

Problem with BufferedImage flickering

Hello I'm writing a small game and it's nearly finished, the only thing that doesn't work is the ImageBuffer. Every 10 miliseconds I call the method repaint(). My paint() method is as follows:

private Graphics2D g2D;

public void paint (Graphics g) {
    BufferedImage bimage = ((Graphics2D)g).getDeviceConfiguration().createCompatibleImage(700, 600, Transparency.OPAQUE);
    g2D = bimage.createGraphics();
    g2D.setFont(font);        
    for(Wall wall: walls){
        wall.paint(g2D);
    }
    g2D.setColor(Color.orange);
    paddle.paint(g2D);
    g2D.drawString(score + "", 150,50);
    g2D.drawString("record: "+topscore  , 350,50);
    g2D.setColor(Color.red);
    ball.paint(g2D);
    g.drawImage(bimage,0,0,this);
}

But this doesn't seem to remove the flickering. I think somehow the screen is cleared before the bufferedimage starts being painted. Can anyone help me with solving this problem? thanks!

Upvotes: 1

Views: 2058

Answers (3)

Chris Dennett
Chris Dennett

Reputation: 22721

You should extend JComponent instead of Canvas, depending on if you are using Swing rather than AWT. Doing this gives you a nice lightweight component and doesn't need you to implement double-buffering support. Then, in your overridden paintComponent(..) draw your image with the provided Graphics object.

On the subject of the original code, creating a new compatible image every single time in paint is blooming horrible (it's a very expensive operation that uses large bytebuffers -- you'll get frequent GC pauses). If you really want double buffering in AWT (which will give you flickering when resizing but should be okay in an applet), you should look into BufferStrategy.

Edit: changed Component to JComponent, oops :)

Upvotes: 1

finnw
finnw

Reputation: 48619

You need to override update:

public void update() {
    paint();
}

The default implementation of update fills the whole region with the background color before calling paint, and that is what is causing the flickering.

Upvotes: 3

camickr
camickr

Reputation: 324108

I can't really tell what you are doing from the code posted, but I'm guessing that you are trying to paint some background image with some moving images on top. If so, then your approach is wrong.

You don't want to recreate the background image every time painting is invoked. Instead the buffered image should be created once outside of the paintComponent() method. Then when you repaint the component you first just paint the image (as the background). Then you paint the paddle and ball on top of the background.

Also another approach is to just use JLabels to represent your paddle and ball. Then to move the component you just change its location. Then only the old/new location of the component needs to be repainted instead of the entire background which is also more efficient.

Upvotes: 1

Related Questions