2013-11-25 116 views
1

我喜欢用双缓冲创建一个小图形库以避免闪烁。画布:双缓冲

所以我创建了一个双缓冲策略Canvas。我假设我strategy.getDrawGraphics()返回当前的后台缓冲区(绘图缓冲区)。比我在缓冲区上绘制一些东西。现在我假设strategy.show()用前台缓冲区翻转后台缓冲区,以便后台缓冲区显示在屏幕上。但我不明白,当我运行下面的代码一个黑色的矩形:

final JFrame frame = new JFrame(); 
frame.setSize(800, 600); 
frame.setVisible(true); 

final Canvas canvas = new Canvas(); 
frame.add(canvas); 

// Double Buffering 
canvas.createBufferStrategy(2); 
final BufferStrategy strategy = canvas.getBufferStrategy(); 

Graphics2D current = (Graphics2D) strategy.getDrawGraphics(); 
current.setColor(Color.BLACK); 
current.fillRect(0, 0, 800, 600); 
strategy.show(); // flip back buffer with front buffer? 
current.dispose(); 
Toolkit.getDefaultToolkit().sync(); 

Thread.sleep(1000); 
frame.dispose(); 

回答

2

三样东西......

  1. 您应该避免混合重和轻重量组件(添加CanvasJFrame
  2. 您应该避免在Event Dispatching Thread的上下文中使用Thread.sleep长时间运行的循环或调用阻塞方法(如I/O)。这可能会阻止您的应用程序被绘制(等等)。相反,您应该考虑使用类似javax.swing.Timer的东西,它会睡在后台线程中,但会在事件调度线程的上下文中触发。默认情况下,Swing组件是双缓冲区。

看一看......

详情

+0

谢谢。这不是真正的答案,但我遵循你的提示。我已经用'JPanel'替换了'Canvas'。因为我不知道哪些事件会调用'paintComponent',所以我使用2个'BufferedImages'并且随时进行交换。这工作正常,没有闪烁。我还将引擎的所有图形方法放在'invokeAndWait'中,比如'drawCircle',所以我确定''BufferedImage'上的所有更改以及对'JPanel'的所有调用都是在UI Thread中执行的。这可能不是很出色,但是它没有闪烁效果很好。那就是我需要的:) – Vertex