3

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()。如上所示,paintComponent()如果您想专门化 UI,文档还建议覆盖。

所以,我想通过代码来了解为什么会这样。

 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()

4

1 回答 1

2

首先来看看...

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

paint是(在这个问题的上下文中)调用的顶级方法(update实际上首先调用,它只是转发到paint)当RepaintManager想要绘制组件时。

paint负责(除其他外)调用paintComponent,paintBorderpaintChildren. 如果您不小心,您可能会损害组件的绘画能力。因此,如果您必须覆盖paint,请确保您正在调用super.paint

需要注意的是,如果子组件被更新,父组件可能不会被重绘,所以它不要试图paint为你的组件提供覆盖。

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

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

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

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

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

您的paint方法还需要快速运行,因此请尽可能避免耗时的操作,例如加载资源或复合循环。如果可以,请创建后备缓冲区并绘制它们

ps-绘画很有趣;)

于 2013-07-18T03:45:06.867 回答