JustAJavaCoder
JustAJavaCoder

Reputation: 47

Java double buffering with buffered image

After a day of searching, I have given up and decided to ask this question: I can't seem to stop the constant flickering of this program:

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

public class Paint {

    BufferedImage image0, image1, image2;
    double rotation0 = 0.0001;
    double rotation1 = 0.0501;
    double rotation2 = 3.0001;

    double add0 = 0.0001;
    double add1 = 0.0016;
    double add2 = 0.000001;


    private int x() {
        return Main.getX() / 2;
    }

    private int y() {
        return Main.getY() / 2;
    }

    public Paint() {
        try {
            image0 = ImageIO.read(new File("circle1.jpg"));
            image1 = ImageIO.read(new File("circle2.jpg"));
            image2 = ImageIO.read(new File("circle3.jpg"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void paint(Graphics g) { 
        // create the transform, note that the transformations happen
        // in reversed order (so check them backwards)
        AffineTransform at0 = new AffineTransform();
        AffineTransform at1 = new AffineTransform();
        AffineTransform at2 = new AffineTransform();

        // 4. translate it to the center of the component
        at0.translate(x(), y() + 10);
        at1.translate(x(), y() + 10);
        at2.translate(x(), y() + 10);

        // 3. do the actual rotation
        rotation0 += add0;
        rotation1 += add1;
        rotation2 += add2;
        at0.rotate(rotation0);
        at1.rotate(rotation1);
        at2.rotate(rotation2);

        // 2. just a scale because this image is big
        at0.scale(1, 1);
        at1.scale(1, 1);
        at2.scale(1, 1);

        // 1. translate the object so that you rotate it around the 
        //    center (easier :))
        at0.translate(-image0.getWidth()/2, -image0.getHeight()/2);
        at1.translate(-image1.getWidth()/2, -image1.getHeight()/2);
        at2.translate(-image2.getWidth()/2, -image2.getHeight()/2);

        // draw the image
        Graphics2D g2d = (Graphics2D) g;
        g2d.drawImage(image0, at0, null);
        g2d.drawImage(image1, at1, null);
        g2d.drawImage(image2, at2, null);
    }
}

IMPORTANT: Everything works but the double buffering, which causes the image to flicker. If you don't mind, please provide code along with the answer.

Upvotes: 1

Views: 1594

Answers (2)

Winter
Winter

Reputation: 4095

Double buffering consists into drawing your content to an internal image and then draw that image on screen. By doing that, the image is never partially printed.

So, instead of drawing your 3 images directly in your Graphics object, try drawing them into a new BufferedImage and draw that image in the Graphics object (screen).

See this official page for more info: https://docs.oracle.com/javase/tutorial/extra/fullscreen/doublebuf.html

Upvotes: 1

Joop Eggen
Joop Eggen

Reputation: 109547

I assume the usage is in a JPanel child. By default a JPanel is double-buffered.

JPanel panel new JPanel() {
    Paint paint = new Paint();

    @Override
    public void paintComponent(Graphics g) {
        paint.paint(g);
    }
};
.. add the panel to the JFrame.

This should work in java swing. Java awt components is another obsolete matter.

Upvotes: 1

Related Questions