【问题标题】:Paint on panel during runtime运行时在面板上绘画
【发布时间】:2026-02-17 06:25:01
【问题描述】:

我有一个面板,我想在上面画东西。 在它被创建的时候在上面绘画是没有问题的。

canvas = new Panel() {
    public void paint(Graphics g) {
        g.setColor(Color.WHITE);
        g.drawLine(0, 0, 10, 10);
    }
};

但是我想在运行时使用它。 本能地,我创造了这样的东西:

Graphics g = canvas.getGraphics();
g.setColor(Color.GREEN);
g.drawLine(10, 10, 20, 20);
canvas.paint(g);

很遗憾,这不起作用。 这可能是一个简单的问题,但我无法通过搜索找到令人满意的结果。 那我该怎么做呢?


抱歉上面的问题。 我刚刚在按钮单击事件上添加了绘制代码,它可以工作。 它只是不适用于父框架的 windowOpened 事件。 任何想法为什么?

【问题讨论】:

  • “我有一个面板,我想在上面画东西” 改为使用BufferedImage

标签: java awt panel


【解决方案1】:

问题在于,只要窗口系统(或操作系统)决定需要在屏幕上重新绘制特定的图形组件,就可以随时调用 paint() 方法。这可能随时发生(通常在调整大小、移动、切换窗口等时)。要查看它发生的频率,只需在 paint() 方法的开头添加一条日志消息。如果您仅在画布上绘制某些东西,则很有可能已绘制,但是另一个重绘请求来自操作系统/窗口系统,并且您的绿线被对象的 paint() “透支”了。 所以答案是任何自定义绘画都应该在paint()中完成。您可以为您的子类添加额外的属性(例如 boolean drawGreenLine),在 paint() 中检查它并采取任何适当的操作,例如:

class MyPanel extends JPanel {

    boolean drawGreenLine;

    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(Color.WHITE);
        g.drawLine(0, 0, 10, 10);
        if (drawGreenLine) {
            g.setColor(Color.GREEN);
            g.drawLine(10, 10, 20, 20);

        }  
    }
};

编辑:正如@MadProgrammer 所建议的,该示例已更改为覆盖paintComponent()。这样组件只负责绘制自己(而不是任何子元素或边框)。

【讨论】:

  • 更改您的示例以使用paintComponet 并将其称为超级方法,我很乐意投票...意思不是我:P
  • JPanel、paintComponent 在 Swing 中使用,而不是在 AWT 中
  • @Hachi 然后使用 Panel 和 paint(),但概念保持不变
【解决方案2】:

尝试g.dispose() 释放 GraphicsContext 的资源

【讨论】:

  • 只有在你创建了图形的情况下,才用 g.create()
  • 在 awt 中的 gc 处理与在 swing 中有点不同。我经常遇到类似的问题,可以通过处理 gc 来解决它们
  • 这没有意义(对我来说),AWT 和 Swing 之间的唯一区别是 AWT 组件有自己的本地对等体,而 Swing 组件共享一个(通常来自*容器) & 支持双缓冲。 Check out the opening paragraph on Painting in Swing