paintComponent() 被调用了 200 次

Posted

技术标签:

【中文标题】paintComponent() 被调用了 200 次【英文标题】:paintComponent() is being invoked 200 times 【发布时间】:2016-02-04 00:24:47 【问题描述】:

我在使用paintComponent() 和repaint() 时遇到了一个奇怪的问题。 正如你在下面看到的,我有一个paintComponent() 类作为我的GUI 的主要JPanel 的内部类。

    // add another panel to centerInner
    tableBottom = new JPanel() 
        @Override
        public void paintComponent(Graphics g) 
            super.paintComponent(g);
            if (!paintImages.isEmpty()) 
                for (PaintImages temp : paintImages) 
                    g.drawImage(temp.getImage(), temp.getX(), temp.getY(), this);
                
            
            if (!extraCards.isEmpty()) 
                for (PaintImages temp1 : extraCards) 
                    g.drawImage(temp1.getImage(), temp1.getX(), temp1.getY(), this);
                
            
        
    ;

这是一个 4 位玩家和一个庄家的二十一点游戏。

repaint() 被 4 个函数调用:

初始绘制的构造函数。 一种更新方法,用于创建对象的ArrayList 以打印初始交易。 另一种更新方法,为每张抽出的牌创建一个ArrayList。 以及清除所有ArrayLists 并重新绘制新的初始交易的重置。

我不会进入后端,但这四种方法中的每一种都只运行所需的次数。每次调用一次。

我的问题是,当repaint() 调用paintComponent 时,paintComponent() 运行了将近 200 次,不包括平均每场比赛运行大约 10 次的 for 循环。

我的问题是:

1) 这是paintComponent 方法的常见行为吗? paintComponent 是否会一遍又一遍地调用自身,直到所有必要的绘制都完成?

2) 这是否与 JPanel tableBottom 有关?此时实际上并没有向 JPanel 添加任何内容,因为它是最顶层的 JPanel。但也许paintComponent 会为每个 JPanel、JFrame、ContentPane、Label 等重复运行,

3) 我在下面的代码中做错了吗?再次通过使用增量和打印语句进行测试,我发现更新方法被调用了适当的次数并且正确地完成了它们的工作。

感谢您的帮助。

【问题讨论】:

您的代码看起来不错;问题可能出在其他地方。 AFAIK paintComponent 每个组件调用一次,因此它不是增量的。也许使用 IDE 中的调试器来查看调用堆栈?可能有一个组件行为不端,从一个paint方法中触发了一个重绘事件。 paintComponent() 将在您的 tableBottom 调整大小或获得曝光(如果没有支持存储)或其父级重置其位置时调用。多久调用一次重绘? (只需覆盖它并让它调用 super.repaint() )? @FredK 在初次抽牌时调用一次,之后每抽一张牌调用一次。我删除了我之前拥有的另外两个。 super.repaint() 会做什么,我会把它放在哪里?目前因为 paintComponent 是一个内部类,我称之为重绘,如 tableBottom.paintComponent() 【参考方案1】:

作为一个内部类,我称之为 repaint like tableBottom.paintComponent()

永远不要直接调用paintComponent() 方法。要重新绘制面板:

tableBottom.repaint();

请求将被传递到 RepaintManager,然后它将结合所有组件的 repaint() 请求,然后根据需要绘制组件。这将使绘画更有效率。

g.drawImage(temp1.getImage(), temp1.getX(), temp1.getY(), this);

“this”表示可以在读取图像时重新绘制图像。有时在图像 I/O 完成之前调用绘制方法。因此,在这种情况下,当 I/O 完成时,将发出另一个绘制请求,以便完全绘制图像。如果您在上课开始时阅读图像并将它们存储在某些数据结构中,那么您可能只使用“null”而不是“this”。

我在下面的代码中做错了吗?

提供的代码看起来很合理,但我们看不到您如何/何时调用绘画代码的上下文。我已经提到了一个问题。

发布一个正确的SSCCE 来说明问题。

【讨论】:

以上是关于paintComponent() 被调用了 200 次的主要内容,如果未能解决你的问题,请参考以下文章

永远不会调用paintComponent()

Java - 方法 repaint() 不调用 paintComponent() 方法

Swing中 paint()与paintComponent()的区别

super.paintComponent(g) 有啥作用?

油漆组件是如何工作的?

使用 JPanel 的 addMouseListener() 和 paintComponent()