对于双缓冲的分析是在坦克大战游戏的设计时开始的,由于当时忙于游戏的整体设计,所以对这一个问题没有进行详细的研究,现在就这个问题来谈谈自己的一些看法。2 T5 s8 a" V! [$ }/ k( ?
分析前提出几个问题:* w, o0 b, M" Z3 y S- q& {: w0 i! a
1、为什么当想屏幕上添加图片之后会有明显的闪烁现象?
+ r0 m( s8 A% q# r9 u" ]0 v, G 2、在awt中如何实现双缓冲?
|' ?4 q8 N+ t4 X A, q 3、如何理解swing内置双缓冲以及比较他与awt中消除闪烁的方法区别在哪里?
1 n/ a* c8 ?& D) M9 y1 K 首先我们来解答第一个问题:
/ a! c7 y- b$ }, z. F 我们在屏幕上自绘图形或者是添加图片都是要通过所在画布的重绘来实现的,因此闪烁的出现必然与重绘机制有着一些关联。在awt中对于窗体画布的重绘其条用顺序是repaint() —>update()—>paint();我们来看看update()的源码:$ z3 F4 B. a" [
Java代码
: P5 E+ S- \% \1 b5 M/ B /**1 x6 L* l. _+ v9 b
* Updates the container. This forwards the update to any lightweight( ]' a, K7 W( I) t
* components that are children of this container. If this method is }( e; Q2 f3 t% w. r
* reimplemented, super.update(g) should be called so that lightweight, S; x% t' z4 o' I* r. x- f
* components are properly rendered. If a child component is entirely
4 m) K% N; e0 r. C- S, m5 A * clipped by the current clipping setting in g, update() will not be9 T7 u( ?! r* S+ V! g2 s
* forwarded to that child.
* i6 ^; H: w& N+ W# N. t *
" h# D/ F1 v, i) n! ^. e * @param g the specified Graphics window
2 g- x" W4 J+ H# y; |$ m. c, { * @see
/ Y+ I" M# C& h5 v! I- E Component#update(Graphics)
/ m" p1 |2 x7 r, W1 G! L% v4 z+ ^ */ {& ~6 |7 r) j2 k0 i
public void update(Graphics g) {8 q; q8 c) a% ~
if (isShowing()) {% w9 u9 u& Q0 [" G' {& R0 J
if (! (peer instanceof LightweightPeer)) {
% H# {, e% T9 @' `# {, |5 M g.clearRect(0, 0, width, height);. p7 d) N1 ?, S/ B) l
}
?& U* e3 ~& _& W2 n4 O% n" P paint(g);4 [; Y f& |6 T0 ~" ]
}8 l( n' n# g' J* s* t( h6 z- D4 x
}
" `+ L- k7 x0 G9 s4 } 从这里我们可以清晰的看到,update中有一个清屏的作用,即g.clearRect(0, 0, width, height);然后再在下面调用paint(g),函数进行重绘。因此到这里的话我们可以在一定程度上对底层的重绘机制有一个了解了。 |