# 仔细研究油漆机制

> 原文： [https://docs.oracle.com/javase/tutorial/uiswing/painting/closer.html](https://docs.oracle.com/javase/tutorial/uiswing/painting/closer.html)

到目前为止，您知道`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 组件的大部分（或全部）绘画如下进行。

1.  `paint()`调用`paintComponent()`。
2.  如果`ui`属性为非 null，则`paintComponent()`调用`ui.update()`。
3.  如果组件的`opaque`属性为 true，则`ui.update()`用背景颜色填充组件的背景并调用`ui.paint()`。
4.  `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 文章。