有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java连续双缓冲解决方案不起作用

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

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

编辑:作为旁注,我使用的是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();
    }
}

共 (1) 个答案

  1. # 1 楼答案

    问题是您没有覆盖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);
        }
    }