Swing中paint、paintComponent和paintComponents的区别

34
在Java Swing中,paint()paintComponent()paintComponents()之间的实际区别是什么?
我试图理解Oracle文档中的解释,但是不太清楚。
2个回答

44
  • 对于 AWT,重写 paint() 方法。
  • 对于 Swing 的顶级容器(例如: JFrameJWindowJDialogJApplet 等),也可以重写 paint() 方法。但是,在这些容器中绘制图形并不总是明智的选择,可能需要单独提出一个问题进行探讨。
  • 对于 Swing 的其他组件(所有从 JComponent 派生的组件),应该重写 paintComponent() 方法。
  • 既不要重写也不要显式调用 paintComponents() 方法,让 API 根据需要自行调用。

注意在重写方法时使用 @Override 注解

这样做有助于指示尝试在 JFrame 中重写 paintComponent(..) 方法(因为它没有此方法),这种情况非常常见。


你好,paint()函数是在构造函数执行完后立即被调用吗? - Sam YC
2
@GMsoF 当需要时,repaint()将自动调用。如果进行动画,则可能会显式调用它。尽管会被过多地调用,但如果太快,一些调用将被合并(忽略)。 - Andrew Thompson
如果您想在JPanel子类上绘制位于同一面板上的组件之上的内容,例如,如果GPanel是JPanel的子类,则还可以覆盖paint()。通过仅覆盖paintComponent,您的“绘画”将位于任何组件(如按钮、其他面板等)之后。但是,使用paint(),您可以在其他组件之上进行绘制。 - PixelMaster

20

你可能会对阅读AWT和Swing中的绘图感兴趣。

其中一句话为:

适用于AWT轻量级组件的规则也适用于Swing组件 - 例如,在渲染时调用paint()方法 - 除了Swing将paint()调用进一步拆分为三个单独的方法,按以下顺序调用它们:

 protected void paintComponent(Graphics g)
protected void paintBorder(Graphics g)
protected void paintChildren(Graphics g)
Swing程序应该重写paintComponent()而不是重写paint()。虽然API允许这样做,但通常没有理由重写paintBorder()或paintComponents()(如果需要重写,请确保知道自己在做什么!)。这种分解使程序更容易地只覆盖它们需要扩展的绘制部分。例如,这解决了先前提到的AWT问题,即未能调用super.paint()会导致任何轻量级子组件都不会出现的问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接