仔细研究绘画机制
到目前为止,您已经知道应该将paintComponent
方法放置在所有绘画代码中。的确,当需要绘画时将调用此方法,但是绘画实际上是使用paint
方法(由java.awt.Component
定义)从类层次结构的更高层次开始的。只要您需要组件,该方法就会由绘画子系统执行。被渲染。它的签名是:
public void paint(Graphics g)
javax.swing.JComponent
扩展了此类,并进一步将paint
方法分解为三个独立的方法,按以下 Sequences 调用:
-
protected void paintComponent(Graphics g)
-
protected void paintBorder(Graphics g)
-
protected void paintChildren(Graphics g)
API 并没有采取任何措施来防止您的代码覆盖paintBorder
和paintChildren
,但是通常来说,没有理由这么做。出于所有实际 Object,paintComponent
将是您将需要重写的唯一方法。
如前所述,大多数标准 Swing 组件的外观都由单独的 UI 委托实现。这意味着标准 Swing 组件的大部分(或全部)绘画按如下进行。
-
paint()
调用paintComponent()
。 -
如果
ui
属性为非 null,则paintComponent()
调用ui.update()
。 -
如果组件的
opaque
属性为 true,则ui.update()
用背景色填充组件的背景并调用ui.paint()
。 -
ui.paint()
呈现组件的内容。
这就是为什么我们的SwingPaintDemo
代码调用super.paintComponent(g)
的原因。我们可以添加一条额外的 注解,以使其更加清晰:
public void paintComponent(Graphics g) {
// Let UI Delegate paint first, which
// includes background filling since
// this component is opaque.
super.paintComponent(g);
g.drawString("This is my custom Panel!",10,20);
redSquare.paintSquare(g);
}
如果您已理解本类中提供的所有演示代码,那么恭喜!您具有足够的实践知识,可以在自己的应用程序中编写有效的绘画代码。但是,如果您想“深入了解”,请参阅本课首页上链接到的 SDN 文章。