帧初始化后多次调用paintComponent

时间:2020-08-26 19:42:21

标签: java swing

考虑示例:

@SuppressWarnings("serial")
public static void main(final String[] args) {
    
    final var frame = new JFrame();
    frame.setPreferredSize(new Dimension(150, 150));
    frame.add(new JPanel() {
        @Override protected void paintComponent(final Graphics g) {
            super.paintComponent(g);
            System.out.println("painting panel");
        }
    });
    frame.pack();
    frame.setLocationRelativeTo(null);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
    SwingUtilities.invokeLater(() -> frame.setVisible(true));
}

有一个带有一个JPanel且带有覆盖的 paintComponent 方法的JFrame,每次调用此方法时,只需将某些内容打印到控制台即可。 每次我运行该程序时,在控制台中都可以看到3次“绘画面板”行。

为什么JPanel的方法 paintComponent 被多次调用而不是一次调用?有没有一种方法可以避免不必要的组件重涂?

1 个答案:

答案 0 :(得分:3)

基本上,不是。但这并没有您想的那么麻烦。

绘画请求由基础系统的图形驱动程序控制。有时,一个应用程序可能只分配少量的视频内存,在这种情况下,系统一次会将一个窗口绘制成一小块。

这意味着仅仅多次调用paintComponent并不意味着正在对该组件进行完全重绘;在调用该方法之前,Graphics对象可能已将一个剪辑设置为仅绘制窗口的一部分。 paintComponent方法不需要为此担心,因为大多数Graphics操作如果知道不会影响当前剪辑范围之外的任何像素,就会立即返回。这里的重点是,多次调用paintComponent并不一定像您想的那样浪费。

而且,正如吉尔伯特(Gilbert)指出的那样,调用pack()将“实现”窗口;即,为窗口分配了实际的本机桌面窗口。 (Java将其称为displayable。)这将触发绘制。显示窗口也可能触发绘画。移动它可能会触发油漆。将鼠标移到它上面可能会触发绘制。

对绘画发生的频率进行假设永远是不安全的。为了可靠地进行绘制,假定可以多次调用您的paintComponent方法。永远不要从绘画方法中更改作为绘画基础的数据。

通常,无法控制何时进行绘画。当然,如果您的程序调用{​​{1}},则可以完全控制调用方式和调用时间。