连续双缓冲解决方案不工作



我试图在使用AWT的paint()方法中对包含多边形的图像进行双缓冲。使用Image对象进行缓冲过程,我将图像背景设置为黑色,将多边形绘制到图像上,然后将缓冲图像绘制到屏幕上。然后我调用repaint()以再次渲染图像。

不幸的是,当重新绘制图像时,我仍然收到伪影。我做错了什么?

EDIT:作为旁注,我使用Java 8。编辑2:我在paint()中调用repaint(),因为我需要不断缓冲图像。该多边形意味着根据用户输入在屏幕上进行转换。

import java.applet.Applet;
import java.awt.*;
public class DoubleBuffer extends Applet {
    int xSize = 900;
    int ySize = 600;
    Image bufferImage;
    Graphics bufferG;
    @Override
    public void init() {
        this.setSize(xSize, ySize);
        //Double buffering related variables
        bufferImage = this.createImage(xSize, xSize);
        bufferG = bufferImage.getGraphics();
    }
    //BUFFERING DONE HERE
    @Override
    public void paint(Graphics g){
        //drawing images to external image first (buffering)
        bufferG.setColor(Color.BLACK);
        bufferG.fillRect(0,0,xSize,ySize);
        bufferG.setColor(Color.WHITE);
        bufferG.drawRect(100, 100, 100, 100);
        //draw the image and call repaint
        g.drawImage(bufferImage, 0, 0, this);
        repaint();
    }
}

问题是您没有重写update,这是响应repaint请求时将调用的方法。对于重量级组件,update的默认实现将首先将组件清除为背景色(可能默认为白色),然后调用paint方法。

正如其他人指出的那样,您不应该在paint方法中调用repaint。你应该使用Timer .

清理后,整个类看起来像:

public class DoubleBuffer extends Applet {
    int xSize = 900;
    int ySize = 600;
    Image bufferImage;
    Graphics bufferG;
    Timer timer=new Timer(200, ev->repaint());
    @Override
    public void init() {
        this.setSize(xSize, ySize);
    }
    @Override
    public void addNotify() {
        super.addNotify();
        //Double buffering related variables
        bufferImage = this.createImage(xSize, xSize);
        bufferG = bufferImage.getGraphics();
        timer.start();
    }
    @Override
    public void removeNotify() {
        super.removeNotify();
        bufferImage = null;
        bufferG = null;
        timer.stop();
    }

    //BUFFERING DONE HERE
    @Override
    public void paint(Graphics g){
        //drawing images to external image first (buffering)
        bufferG.setColor(Color.BLACK);
        bufferG.fillRect(0,0,xSize,ySize);
        bufferG.setColor(Color.WHITE);
        bufferG.drawRect(100, 100, 100, 100);
        //draw the image and call repaint
        g.drawImage(bufferImage, 0, 0, this);
    }
    @Override
    public void update(Graphics g) {
        // now not clearing the background as we expect paint() to fill the entire area
        this.paint(g);
    }
}

最新更新