为什么在没有显式调用 repaint() 的情况下连续异步调用paintComponent()?

2024-04-26

所以这个问题有两个部分,我认为可能是相关的,而且大多是抽象的。简而言之,这就是我正在做的事情:

我有一个JFrame with a JPanel还有一些child JPanels每个有 3 个JButtons在上面。我还创建了一个JComponent called glassPanel为了JFrame (i.e. myJFrame.setGlassPane(glassPanel)),这使我能够在 JPanel 和按钮上进行绘制。

(1) 本质上是通过单击 a 上的所有 3 个按钮来触发JPanel, glassPanel被设定为Visible(这似乎然后调用paintComponent())。这与第一个问题有关。

(2) In paintComponent()我使用双缓冲 http://www.cs.tut.fi/lintula/manual/java/tutorial/uiswing/painting/overview.html, onto glassPanel。这涉及到第二个问题。

这是我的相关 GlassPanel 类代码(这不是 SSCCE,因为它现在是一个抽象问题):

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;
import javax.swing.JComponent;


public class GlassPanel extends JComponent {

     @Override
     protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        setDoubleBuffered(true);
        Graphics2D g2 = (Graphics2D) g;

        g2.drawRect(x,y,width,height);
        g2.fillRect(x,y,width,height);

        g2.drawImage(img, x, y, this);
    }
}

通过放置一个System.out.print在 PaintComponent() 方法中的声明,我可以告诉它被连续地和异步地调用。有关我认为如何进行调用的信息,请参阅 (1)。另外,假设我绝对确定没有人打电话给repaint()代码中的任何位置(我已经检查了很多很多次)。这是第一个问题的基础。

我第一次点击 3 个按钮时,一切都很顺利。矩形和图像都会立即绘制。但是,当我单击接下来的 3 个按钮时(此时,glassPanel已经是setVisible(true)第一个矩形和图像仍在屏幕上,绘制在前 3 个按钮上),第二个矩形和图像仅部分加载。当我点击远离JFrame并进入我运行程序的 Eclipse 窗口,调用次数paintComponent()每次快速增加相同的量并且部分加载的图像和矩形立即完全显示在背景中JFrame。当我单击返回 JFrame 时,调用数量再次增加了确切的数量)。这是第二个问题的基础。

UPDATE: Here's http://www.cs.tut.fi/lintula/manual/java/tutorial/uiswing/painting/overview.html我读过的东西:

另外,当 GUI 被另一个窗口覆盖然后变成 如果没有发现,绘画系统会调用paintComponent方法 绘画面积等于新未覆盖的面积。

我的问题是:

(1) 为什么可能paintComponent()被如此多地称为没有repaint()?或者,类似的问题,什么可能调用paintComponent()?

更新:做了一些数学计算后,我坚信每个组件(所有按钮和面板)都会不断调用它。但仍然没有调用 repaint()...

(2) 为什么图像会部分加载,直到我从 JFrame 窗口获得焦点?

请注意,我尝试了很多事情:(a)创建自己的双缓冲区并且不使用双缓冲区(我知道它主要用于动画),(b)覆盖和不覆盖paintComponent(),(c) 绘制和不绘制图像(矩形仍然需要时间来加载),(d) 绝对确保没有repaint(), (e) 使用和不使用SwingUtilities.invokeLater(new Runnable() { public void run() { //stuff});,(f)做了一个if语句仅 setVisible(true) 一次。

如果必须的话,我可以尝试通过 SSCCE,但我确实认为这些更抽象。谢谢!


嗯,我想我已经回答了这两个问题。首先,为什么 PaintComponent() 被连续调用,是因为它实际上并没有被连续调用。当它第一次显示 GUI 时,所有组件都会调用它。当 Eclipse 窗口覆盖它然后又揭开它时,它会被调用更多次。

对于第二个,它与clipBounds of the Graphics2D物体/事物。我发现如何clipBounds每次绘制调用都会发生变化,所以当我将剪辑设置在开始时paintComponent()方法,图像立即显示。 (顺便说一句,它看起来很棒!)。

稍有不同的是:显示图像后,每次单击按钮都会对图像执行一些操作。不过我还没弄清楚具体是什么。它看起来几乎就像是在旧图像上重新绘制相同的图像。

所以我必须弄清楚如何保留旧图像,但在适当的时候绘制新图像,并且仅将新图像绘制/添加到glassPanel.

更新:打电话repaint()单击每个按钮后立即有一点帮助。但当按下按钮时,它仍然会导致图像有些闪烁,就像添加了另一层一样,然后当用户松开按钮时,图像又恢复正常。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么在没有显式调用 repaint() 的情况下连续异步调用paintComponent()? 的相关文章

随机推荐