我有一个带有JLabel的JFrame,它包含一个包含BufferedImage的ImageIcon。 BufferedImage的graphis是通过几个不同的图形调用绘制的,例如drawOval(),drawRectangle()等,其上有许多绘制的形状。随着时间的推移,或者用户在面板上进行平移/缩放,图形会重新绘制,因此我们可以每秒重绘几次。
在尝试添加双缓冲之前,图像重绘速度很慢,但我的JComponents会渲染正常。用户可以拖动和调整标签大小,图像将重绘多次。我决定尝试双缓冲。
使用我目前的双缓冲实现,JLabel / Graphics重绘并显示非常流畅。但是,JFrame有其他控件(JMenuBar,JSlider,JComboBox等)不能正常渲染和闪烁很多。我必须手动重绘()它们,但随后它们会闪烁。双缓冲怎么办?如何让我的图像顺利重绘,还能让我的JComponetns不闪烁?
该视图使自己做双重缓冲。我还尝试将setIgnoreRepaint(true)
设置为解决问题的方法。
this.createBufferStrategy(2);
...
m_graphicsLabel.setIcon(new ImageIcon(bufferedImage));
当新图形可用时,辅助类会调用以下方法。我手动重新绘制JComponents,否则它们根本不会出现。但它们闪烁,因为这种方法可以每秒多次调用。
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);
}