这些Java教程是针对JDK 8编写的。本页面中描述的示例和实践不利用后续版本中引入的改进,并可能使用不再可用的技术。
请参阅Java语言变更以获取Java SE 9及其后续版本中更新的语言特性的摘要。
请参阅JDK发布说明了解有关所有JDK版本的新功能、增强功能以及已删除或已弃用选项的信息。
到目前为止,您已经知道paintComponent
方法是放置所有绘制代码的位置。的确,当绘制时间到来时,这个方法将被调用,但实际上绘制从类层次结构的更高层次开始,即paint
方法(由java.awt.Component
定义)。每当需要渲染您的组件时,绘制子系统将执行此方法。其签名为:
public void paint(Graphics g)
javax.swing.JComponent
扩展了这个类,并将paint
方法进一步分解为三个独立的方法,按照以下顺序调用:
protected void paintComponent(Graphics g)
protected void paintBorder(Graphics g)
protected void paintChildren(Graphics g)
API没有阻止您的代码重写paintBorder
和paintChildren
,但一般来说,您没有理由这样做。对于所有实际目的而言,paintComponent
将是您唯一需要重写的方法。
如前所述,大多数标准Swing组件的外观和感觉由单独的UI委托实现。这意味着大多数(或全部)标准Swing组件的绘制过程如下所示。
paint()
调用paintComponent()
。ui
属性非空,paintComponent()
调用ui.update()
。opaque
属性为true,ui.update()
用背景颜色填充组件的背景并调用ui.paint()
。ui.paint()
渲染组件的内容。这就是为什么我们的SwingPaintDemo
代码调用super.paintComponent(g)
。我们可以添加一个额外的注释来更清楚地说明:
public void paintComponent(Graphics g) { // 让UI Delegate先绘制,包括 // 填充背景,因为 // 这个组件是不透明的。 super.paintComponent(g); g.drawString("This is my custom Panel!",10,20); redSquare.paintSquare(g); }
如果您已经理解了本课程中提供的所有演示代码,恭喜!您拥有足够的实际知识来在自己的应用程序中编写高效的绘制代码。然而,如果您想更深入地了解“底层工作原理”,请参阅本课程第一页链接的SDN文章。