JAVA调整窗口大小后调用的绘制(图形)太多!

JAVA调整窗口大小后调用的绘制(图形)太多!,java,graphics,canvas,resize,paint,Java,Graphics,Canvas,Resize,Paint,我有个问题。最近,我正在研究使用Java实现硬件渲染的方法。我的目标不是使用像OpenGL这样的外部库。我在一个网站上找到一篇文章,详细介绍了如何做到这一点 这就是我重命名某些项目的代码: @Override public void paint(Graphics g) { createVolatileImage(); do { GraphicsConfiguration gc = getGraphicsConfigurat

我有个问题。最近,我正在研究使用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());
    }
不幸的是,如果我调整窗口的大小,类Canvas中的paint Graphics方法会在一秒钟内被调用1000次,从而导致OutOfMemoryException

以前有人遇到过这种情况吗?
提前多谢

您得到OutOfMemoryException的原因是因为您从未清理过您的VolatileImage。在我看来,每次调用paint时,您都会分配一个新的VolatileImage,这种情况可能会发生数百次,或者在您的情况下每秒发生1000次以上。除非您释放VolatileImage使用的内存或修复一些问题,以便只分配一次而不是每帧一次,否则应用程序的内存空间将膨胀,直到JVM崩溃。尝试在渲染循环结束时添加对OffScreengGraphics.dispose的调用。也请阅读

编辑:


另一个有用的方法。

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

如中所述,这是在AWT中绘制时的预期行为。特别是,调整零部件大小时会发生系统触发的绘制操作。正如@rjacks所指出的,您需要处理在paint中创建的任何资源。

我认为从paint例程内部调用validate是不明智的,因为validate可以调用调用paint的repaint,在Javadocs中设置一个无限循环,即do-while循环,检查是否有内容物丢失。是否在组件喷漆方法中?我是否会在。。。还是之后?因为我以前试过。。。没有用。我认为在while循环之前进行处理会达到预期效果。也许你可以发布更多的代码?对于简单场景,绘制方法每秒调用1000次以上并不少见,也许问题出在其他地方?我怀疑它是否出在其他地方。应用程序只是一个添加了画布的框架。canvas类覆盖了paint。。。和更新。非常感谢您提供其他有用的参考资料。这正是我需要的。当我开始重写这段代码时,我肯定会利用这个网站。