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

时间:2015-12-29 23:40:19

标签: java swing jpanel

我正在开发一个应用程序,我逐个像素地绘制所有内容。在此过程中,我注意到某个paintComponent()的{​​{1}}方法被调用了两次。所以我创建了以下 MCVE ,以确定它是否与绘制到屏幕上的其他组件有关,或者它是否只是一个独立的问题:

App.java

JPanel

MainFrame.java

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

Board.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);
    }
}

但是控制台日志显示public class Board extends JPanel { @Override protected void paintComponent(Graphics g) { super.paintComponent(g); System.out.println("CALLED"); } } 两次。

我对"CALLED"特别感兴趣,因为它是所有应用程序的魔法工作的方法,因此我需要控制每个绘制周期。

这次双重调用paintComponent()背后的原因是什么?

还有另外一种方式我可以用其他方式做一些一次吗? (我的意思是,不是在paintComponent(),如果它被调用两次,无论如何)

2 个答案:

答案 0 :(得分:4)

  

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

因为只要插件确定需要它就会调用它。

  

我需要控制这种行为。

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

这个难题的逻辑方法是将所有内容绘制成BufferedImage,显示在ImageIcon中显示的JLabelrepaint()。然后,无论调用标签的http://pl.dbpedia.org/page/方法多少次,该应用程序。仍然只需要生成一次像素。

实施例

  1. Draw in an image inside panel

    enter image description here

  2. Multiple calls of paintComponent()

    enter image description here

  3. Drawing the Cannabis Curve

    enter image description here

答案 1 :(得分:0)

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