[Java 2D/Swing基础] 双缓冲;paint()、repaint()与update()

★ 双缓冲工作原理

 

(图片来自http://www.vckbase.com/document/viewdoc/?id=1612,更多文字介绍请参阅该短文)



★ 不用双缓冲为什么产生闪烁

 

  我们知道屏幕的工作方式可以简化理解为,定时扫描显存并将之通过显像管成像映射到屏幕上。我们在绘制图像时通常采用替代方式:首先用背景色或背景图片将之前内容抹掉,然后再在背景色或背景图片上绘制新内容。则,如下图所示将一副笑脸的图片替换为大笑(横坐标轴为屏幕刷新,红线和绿线代表不同的绘制时序):

[Java 2D/Swing基础] 双缓冲;paint()、repaint()与update()

   红线是闪烁的情况:在扫描1时,我们看到笑脸;扫描2时,我们看到纯背景色,扫描3时,我们看到大笑;绿色是不闪烁的情况:在扫描1和2时,我们看到笑脸,扫描3时,我们看到大笑。闪烁是由于我们交替看到了背景色和前景。

  由此我们看出,需要绘制场景的复杂度并不是闪烁产生的关键因素,即使是很简单的绘制由于扫描和绘制的时序配合不当也会产生闪烁。而双缓冲的应用则使得笑脸和大笑之间的纯背景色绘制在offscreen中进行,从而消除了闪烁。
  另一方面,闪烁的产生是由于使用了替代的绘制方式。如果我们只是使用增量的绘制方式,即只是单纯的向画板添加新内容而不使用背景色或背景图片清除原内容,也可以避免闪烁的产生。简单的原理可以参阅
http://www.cnitblog.com/fangyuanning/archive/2009/07/19/60204.aspx,该短文指出了在绘制区域极其规整和集中的时的处理方法;下文关于update()的说明也会有避免闪烁很好的演示。

★ paint(),repaint() and update()

 

  一个包含更多内容的AWT&Swing绘制内容应该参阅官方文章<Painting in AWT and Swing>,该文详细的介绍了我们在处理AWT&Swing的painting过程中应该关心的问题。本文上文提到的增量方式避免闪烁的例子出现在Painting in the AWT -> The Paint Method 章节的倒数第2段,但同时应当注意到,由于该文后面提到的原因——Swing并不使用update()方法,增量防止闪烁的做法在Swing是不可行的。该文章叙述“the opaque property is primarily a contract with the repaint system”是对Jcomponent组件的opaque属性很好的诠释,同样的还有对OptimizedDrawingEnabled属性也做出了很好的解释。看完该全文我想对于SWT与Swing绘制的主题就不会有更多疑问了。
  Good luck, though.

你可能感兴趣的:(java,工作,swing)