为什么 paintComponent 方法被调用了两次?

Why is the paintComponent method called twice?

我正在开发一款应用程序,我可以逐像素绘制所有内容。在这个过程中,我注意到某个JPanelpaintComponent()方法被调用了两次。所以我创建了以下 MCVE 来弄清楚它是否与绘制到屏幕上的其他组件有关,或者它是否只是一个独立的问题:

App.java

public class App {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new MainFrame("Paint test"));
    }
}

MainFrame.java

public class MainFrame extends JFrame {
    private Board mBoard;

    public MainFrame(String title) {
        super(title);

        setMinimumSize(new Dimension(400, 400));
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        setLayout(new BorderLayout());

        mBoard = new Board();
        add(mBoard, BorderLayout.CENTER);

        setVisible(true);
    }
}

Board.java

public class Board extends JPanel {

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        System.out.println("CALLED");
    }
}

但是控制台日志显示 "CALLED" 两次。

我对 paintComponent() 特别感兴趣,因为它是应用程序所有魔法发挥作用的方法,所以我需要控制每个绘制周期。

两次调用 paintComponent() 背后的原因是什么?

有没有其他方法可以用其他方式 once 来画画? (我的意思是,不在 paintComponent() 中,如果它无论如何都会被调用两次)

阅读评论中的简短讨论后,我有一个建议。准备 Shape 对象并将其保存为资源。这将保存运行时计算。当程序启动时,在单独的线程中加载文件(与加载 GUI 并行),然后只绘制该对象。只画画应该不会很贵所以就算调用几次应该也没有问题。

Why is the paintComponent method called twice?

因为每当 plug-in 确定需要它时都会调用它。

I need to control that behavior.

最好使用有效的方法,而不是追求无法实现的目标。

不过,解决这个难题的逻辑方法是将所有内容绘制到显示在 JLabel 中的 BufferedImage(显示在 JLabel 中的 ImageIcon。那么无论标签的repaint()方法被调用多少次,app.仍然只需要生成一次像素。

例子

  1. Draw in an image inside panel

  2. Multiple calls of paintComponent()

  3. Drawing the Cannabis Curve