我有一个带有 JLabel 的 JFrame,其中包含一个包含 BufferedImage 的 ImageIcon。BufferedImage 的图形是用几个不同的图形调用绘制的,例如 drawOval()、drawRectangle() 等,上面有许多绘制的形状。随着时间的推移,或者用户在面板上平移/缩放,图形会被重绘,所以我们可能每秒重绘几次。
在尝试添加双缓冲之前,图像重绘很慢,但我的 JComponents 会呈现正常。图像将重绘多次,因为用户可以拖动标签并调整其大小。我决定尝试双缓冲。
使用下面我当前的双缓冲实现,JLabel/Graphics 重绘并显示非常流畅。但是,JFrame 有其他控件(JMenuBar、JSlider、JComboBox 等)无法正确呈现并且闪烁很多。我必须手动重新绘制()它们,但它们会闪烁。双缓冲我做错了什么?如何让我的图像顺利重绘,同时让我的 JComponetns 不闪烁?
视图将自己设置为进行双重缓冲。我还尝试将设置setIgnoreRepaint(true)
作为解决问题的一种方式。
this.createBufferStrategy(2);
...
m_graphicsLabel.setIcon(new ImageIcon(bufferedImage));
当有新图形可用时,助手类将调用下面的此方法。我正在手动重新绘制 JComponent,否则它们根本不会出现。但是它们会闪烁,因为这种方法每秒可以调用多次。
public void newViewGraphicsAvailable() {
m_xAxisZoomSlider.repaint();
m_yAxisZoomSlider.repaint();
lblZoom.repaint();
lblYZoom.repaint();
m_comboBox.repaint();
m_menuBar.repaint();
m_layersMenu.repaint();
}
这是通过调用 graphics.drawOval() 等操作图形对象的辅助类。
private void drawGraphics(){
BufferedImage blankImage = createBlankImage();
Graphics g = null;
try {
g = m_bufferedStrategy.getDrawGraphics();
g.drawImage(blankImage, 0, 0, null);
m_imageDrawer.draw((Graphics2D) g);
} finally {
g.dispose();
}
m_bufferedStrategy.show();
Toolkit.getDefaultToolkit().sync();
view.newGraphicsAvailable();
}
private BufferedImage createBlankImage()
{
short[] backgroundPixels = new short[Width * Height];
for(int index = 0; index < backgroundPixels.length; index++) {
backgroundPixels[index] = 0;
}
DataBuffer dbuf = new DataBufferUShort(backgroundPixels, WaterfallHeight * WaterfallWidth, 0);
int bitMasks[] = new int[]{0xFFFF};
SampleModel sampleModel = new SinglePixelPackedSampleModel(
DataBuffer.TYPE_USHORT, WaterfallWidth, WaterfallHeight, bitMasks);
WritableRaster raster = Raster.createWritableRaster(sampleModel, dbuf, null);
return new BufferedImage(m_indexColorModel, raster, false, null);
}