paint,paintComponent,repaint等之间的关系

时间:2013-07-18 02:41:09

标签: java swing

paint方法:

Invoked by Swing to draw components. Applications should not invoke paint directly, 
but should instead use the repaint method to schedule the component for redrawing.

This method actually delegates the work of painting to three protected methods: 
paintComponent, paintBorder, and paintChildren. They're called in the order listed 
to ensure that children appear on top of component itself. Generally speaking,
the component and its children should not paint in the insets area allocated to the
border. Subclasses can just override this method, as always. A subclass that just 
wants to specialize the UI (look and feel) delegate's paint method should just 
override paintComponent.

Parameters:
    g the Graphics context in which to paint

public void paint(Graphics g)

我多次阅读不要覆盖paint(),而是覆盖paintComponent()。如上所示,如果您想要专门化UI,文档还建议覆盖paintComponent()

所以,我想跟踪代码,看看为什么会这样。

 protected void paintComponent(Graphics g) 
 {
     if (ui != null) 
     {
         Graphics scratchGraphics = (g == null) ? null : g.create();

         try 
         {
             ui.update(scratchGraphics, this);
         }
         finally 
         {
             scratchGraphics.dispose();
         }
     }
 }

有很多方法可以追踪,但为了简明起见,这里是update()

public void update(Graphics g, JComponent c) 
{
    if (c.isOpaque()) 
    {
        g.setColor(c.getBackground());
        g.fillRect(0, 0, c.getWidth(),c.getHeight());
    }

    paint(g, c);
}

调用paint()的重载版本,paint()本身调用paintComponent()。所以,我想我只想弄清楚这里到底发生了什么。我对Swing很新;有很多类,很难跟踪所有这些类,特别是在我使用GUI的知识有限的情况下。

这些方法是否经常互相调用,从而在屏幕上显示图像的幻觉?如果是这样,如果您覆盖paint()而不是paintComponent,为什么这么重要?我认为我的逻辑在某些方面存在缺陷或缺乏,考虑到对于应用程序,文档建议不要直接调用paint(),而是建议调用repaint()。所以,基本上,我只是想了解paint()paintComponent()repaint()等之间的整体关系。

1 个答案:

答案 0 :(得分:2)

首先看看......

第二个应该是所有Swing开发人员的必读阅读。

paint(在此问题的上下文中)update时调用的顶级方法(paint实际上先调用RepaintManager)想要绘制一个组件。

paint负责(除其他事项外)调用paintComponentpaintBorderpaintChildren。如果你不小心,你可能会损害你的组件绘画能力。因此,如果您要覆盖paint,请确保拨打super.paint

值得注意的是,如果更新了子组件,则可能不会重新绘制父组件,因此不会尝试使用paint为组件提供叠加层。

paintComponent负责绘制组件的“背景”。这基本上代表了外观。

对于类似JPanel的情况,它会用背景颜色填充背景(如果设置为不透明)。在类似JTable的情况下,它将绘制行,列和单元格值。

总是调用super.paintComponent非常重要,尤其是在处理透明组件时。

repaint将向RepaintManager发出请求,该请求可以合并绘制请求,以减少引发的绘制事件的实际数量。这有助于提高性能。

这里要注意的重要一点是你不能控制油漆过程,所以不要尝试,而是使用它。

您的paint方法也可以快速运行,因此请尽量避免耗费时间,例如加载资源或复合循环。如果可以,请创建后备缓冲区并将其绘制为

ps-油漆很有趣;)