Double Buffering ineffective?

This has got to be the oldest gripe in the book, but a friend of mine using the Java2D api has been experiencing flicker problems using the following code. As far as I can tell it uses double-buffering correctly, and I’ve seen the same problems myself when I run it. I’ve thrown every trick in the book I know at it, even going so far as “bufferInt = ((DataBufferInt)(buffer.getRaster().getDataBuffer())).getData();”, to no avail. Any clues as to the underlying problem would be appreciated.


import java.awt.*; 
import java.awt.event.*; 
import java.awt.image.*; 
import javax.swing.*; 

public class ImageFrame extends JFrame implements ActionListener{ 
    private BufferedImage frameImg; 
    private Graphics2D frameImgG; 
    
    private Image plainsI, warriorI; 
    
    private int xloc; 
    private Timer xlocTimer; 
    
    public ImageFrame() { 
        super("Image testing"); 
        
    } 
    
    public void run() { 
        plainsI = Toolkit.getDefaultToolkit().getImage("Plains01.jpg"); 
        warriorI = Toolkit.getDefaultToolkit().getImage("Warrior.png"); 
        
        frameImg = new BufferedImage(800, 600, 
                BufferedImage.TYPE_INT_RGB); 
        frameImgG = frameImg.createGraphics(); 
        
        xloc = 150; 
        
        xlocTimer = new Timer(200, this); 
        xlocTimer.start(); 
        
        setSize(800, 600); 
        setVisible(true); 
    } 
    
    public void paint(Graphics g) { 
        super.paint(g); 
        
        frameImgG.drawImage(plainsI, 0, 0, 800, 600, null); 
        
        frameImgG.drawImage(warriorI, xloc, 400, null); 
        
        g.drawImage(frameImg, 0, 0, null); 
    } 
    
    
    /** Respond to Timer's event */ 
    public void actionPerformed(ActionEvent a) { 
        repaint(); 
        xloc+=10; 
        if (xloc > 500) { 
            xlocTimer.stop(); 
        } 
        
    } 
    
    /** 
     * @param args the command line arguments 
     */ 
    public static void main(String[] args) { 
        
        ImageFrame application = new ImageFrame(); 
        application.run(); 
        application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
        
    } 
    
} 

Why not just BufferStrategy?

With manual double buffering update() needs to be overwritten.

you’re using a BufferedImage as BackBuffer which is done in SW only.

Use BufferStrategy or VolatileImage for hw-accerlated double buffering.

lg Clemens

If you’re using repaint() instead of active rendering, why not just use the built-in swing double buffering? Also, what is the effect of overriding paint instead of paintComponent?