连续双缓冲解决方案不起作用
Continous double buffering solution not working
我正在尝试使用 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();
}
}
问题是您没有重写 update
这是响应 repaint
请求时将调用的方法。对于重量级组件,update
的默认实现将首先将组件清除为背景色(可能默认为白色),然后调用您的 paint
方法。
正如其他人所指出的,您不应该从 paint
方法中调用 repaint
。你应该使用 Timer
.
清理后,整个class看起来像:
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);
}
}
我正在尝试使用 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();
}
}
问题是您没有重写 update
这是响应 repaint
请求时将调用的方法。对于重量级组件,update
的默认实现将首先将组件清除为背景色(可能默认为白色),然后调用您的 paint
方法。
正如其他人所指出的,您不应该从 paint
方法中调用 repaint
。你应该使用 Timer
.
清理后,整个class看起来像:
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);
}
}