简体   繁体   English

Java双缓冲带缓冲图像

[英]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. 如果您不介意,请提供代码以及答案。

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). 因此,与其直接在Graphics对象中绘制3张图像,不如尝试将它们绘制到新的BufferedImage中,然后在Graphics对象(屏幕)中绘制该图像。

See this official page for more info: https://docs.oracle.com/javase/tutorial/extra/fullscreen/doublebuf.html 有关更多信息,请参见此官方页面: https : //docs.oracle.com/javase/tutorial/extra/fullscreen/doublebuf.html

I assume the usage is in a JPanel child. 我假设用法是在JPanel子级中。 By default a JPanel is double-buffered. 默认情况下,JPanel是双缓冲的。

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 swing中工作。 Java awt components is another obsolete matter. Java awt组件是另一个过时的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM