Search code examples
javaswingawtbufferedimagepaintcomponent

How do you write every paintComponent call simultaneously to BufferedImage?


How do you write every every repaint call (direct or not) by a JPanel-type (i.e. a custom class which extends/inherits from JPanel) to a BufferedImage ?

Doing this sort of thing inside the custom class' paintComponent does not work:

protected void paintComponent(Graphics g) {
    super.paintComponent(g); 
    Graphics2D G2 = (Graphics2D) g;

    // ... draw objects

    BufferedImage imageBuffer = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
    G2 = imageBuffer.createGraphics();

    // Which doesn't work, because with that method it seems you would
    // need to call paint() on Graphics2D reference here. 
    // And to do so would then throw an Illegal Exception.
}

The resulting BufferedImage is the correct size of the JPanel-type class which calls paintComponent, but the image is black (i.e. empty) - which is entirely logical because createGraphics() alone does nothing.

I know of Rob Camick's ScreenImage code - but that seems intended for a single screenshot at initialisation of the program.

What leaves me confused is that what paintComponent does must be held in memory before being displayed on-screen... So is there a way of grabbing that every time and saving it into a BufferedImage ?


Solution

  • What about this approach? The difference from you posted code is that you need to do all your custom drawing onto your BufferedImage. Then you draw just one thing onto the component: the BufferedImage.

    public void paintComponent(Graphics g) {
        super.paintComponent(g); 
        Graphics2D g2 = (Graphics2D) g;
    
        BufferedImage imageBuffer = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
        Graphics imageG2 = imageBuffer.createGraphics();
    
        // do custom painting onto imageG2...
    
        // save imageBuffer
    
        g2.drawImage(imageBuffer, 0, 0, this);  // draw onto component
    }