5.5 界面绘制
用户界面组件库中的组件都要在屏幕上绘制之后显示给用户。Java平台上的AWT和Swing也不例外。在Swing还没出现之前,AWT并不需要负责管理组件的界面绘制工作,因为这些是由操作系统底层的原生控件负责完成的。在Swing出现之后,由于Swing组件的界面是自己绘制组件的,因此需要对绘制的过程进行管理,而作为Swing基础的AWT也需要有相应的实现。
5.5.1 AWT中的界面绘制
AWT中的界面绘制围绕着Component类中的paint方法展开。这个方法用来绘制AWT组件的界面。当系统认为某个组件需要绘制的时候,就会调用该组件的paint方法,并传入预先配置好的java.awt.Graphics类的对象作为参数。在paint方法的实现中,需要利用这个Graphics类的对象所提供的方法来完成绘制。
有两类情况会造成paint方法被调用。第一类是由系统根据组件的状态来决定的,可能造成paint方法被调用的情况包括:组件第一次通过setVisible方法设置为在屏幕上可见的时候,组件的大小发生改变的时候,以及组件的部分区域需要重新绘制的时候。第二类情况是程序本身通过repaint方法来要求组件重新进行绘制,这通常是因为程序的内部状态发生了改变,组件需要重新绘制以反映这些变化。调用repaint方法也会使得paint方法被调用。程序不应该直接调用paint方法,而是通过调用repaint方法来发出通知,由系统来调用paint方法。
在paint方法中进行界面绘制时需要考虑的一个重要属性是本次绘制时的剪辑区域(clip bounds)。通过作为paint方法实际参数的Graphics类的对象的getClipBounds方法可以获取这个剪辑区域。剪辑区域的含义是只有这个区域内的部分界面需要重新绘制,其余部分则不需要。如果是系统产生的paint方法调用,剪辑区域的范围由系统来确定;如果是程序通过repaint方法产生的paint方法调用,剪辑区域可以通过调用repaint方法时的参数来指定。在paint方法的实现中,应该考虑到剪辑区域的存在,只重新绘制剪辑区域即可,而不是在任何情况下都把组件的全部区域重新绘制。考虑剪辑区域的重要好处是可以提高界面绘制时的性能。在程序中调用repaint方法的时候,应该首先计算出需要重新绘制的区域的范围,再把该区域作为调用时的参数传入。如果使用不带参数的repaint方法,则说明组件的全部区域都需要重新绘制。