Java的;调整窗口大小后,paint(Graphics)调用太多了!

时间:2011-06-21 23:08:03

标签: java graphics canvas resize paint

我有一个问题。最近,我正在研究使用Java实现硬件渲染的方法。我的目标不是使用OpenGL等外部库。我在网站上发现了一篇详细说明如何操作的帖子。

这就是代码(我重命名了一些项目):

    @Override
    public void paint(Graphics g) {
        createVolatileImage();

        do {
            GraphicsConfiguration gc = getGraphicsConfiguration();
            Graphics offscreenGraphics = volatileImage.getGraphics();

            int validationCode = volatileImage.validate(gc);
            if (validationCode == VolatileImage.IMAGE_INCOMPATIBLE) {
                createVolatileImage();
            }

            offscreenGraphics.setColor(getBackground());
            offscreenGraphics.fillRect(0, 0, getSize().width, getSize().height);

            offscreenGraphics.setColor(getForeground());
            paint(offscreenGraphics);

            g.drawImage(volatileImage, 0, 0, this);
        } while (volatileImage.contentsLost());
    }

    private void createVolatileImage() {
        GraphicsConfiguration gc = getGraphicsConfiguration();
        volatileImage = gc.createCompatibleVolatileImage(getWidth(), getHeight());
    }

不幸的是,如果我调整窗口大小 - paint(Graphics)方法(在Canvas类中)会在一秒内被调用1000次,从而导致OutOfMemoryException。

之前有没有遇到过这个? 非常感谢提前!

3 个答案:

答案 0 :(得分:0)

您获得OutOfMemoryException的原因是因为您从未清理过VolatileImage。我看到它的方式是,每次调用VolatileImage时都会分配一个新的paint(),这可能会发生数百次(或者在你的情况下超过一千次)每秒。除非您释放VolatileImage使用的内存或修复内容,以便分配一次而不是每帧一次,否则应用程序的内存空间将会膨胀,直到您崩溃JVM为止。尝试在渲染循环结束时添加对offscreengraphics.dispose()的调用。另请阅读Javadoc

编辑:

另一个有用的reference

答案 1 :(得分:0)

我真的不认为你的paint方法应该有一个循环。它应该为每个需要绘制的动作绘制一次,然后返回。当您拖动屏幕时,OS / env将负责将重绘消息一遍又一遍地发送到您的应用程序。如果可能的话你应该重新绘制然后返回。没有循环检查内容是否丢失,操作系统会告诉你何时进行绘画。

答案 2 :(得分:0)

Painting in AWT and Swing中所述,这是在AWT中绘画时的预期行为。特别是,在调整组件大小时会发生系统触发的绘制操作。正如@rjacks所说,您需要dispose() paint()中创建的所有资源。