开发者

Java; paint ( Graphics ) called too much after resizing window!

I have a question. Recently I was looking into ways to implement hardware rendering using Java. My goal was not to use an external library such as OpenGL. I found a post on a website that detailed how to do so.

This is what the code was (I renamed some items):

    @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(volat开发者_C百科ileImage, 0, 0, this);
        } while (volatileImage.contentsLost());
    }

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

Unfortunately, if I resize the window - the paint ( Graphics ) method (in the class Canvas) gets called like 1,000 times within a second, causing an OutOfMemoryException.

Has anyone encountered this before? Thanks a lot in advance!


The reason you are getting an OutOfMemoryException is because you never clean up your VolatileImage. The way I see it, you are allocating a new VolatileImage every time paint() is called, which can happen many hundreds (or in your case over a thousand) times per second. Unless you free the memory used by the VolatileImage or fix things so that you make the allocation once instead of once per frame, your application's memory space will balloon until you crash the JVM. Try adding a call to offscreengraphics.dispose() at the end of your rendering loop. Also read the Javadoc.

EDIT:

Another useful reference.


I really don't think you should have a loop in your paint method. It should paint a single time for each action that needs a paint, then return.When you drag the screen, the OS/env will take care of dispatching repaint messages over and over to your app. You should repaint if possible then just return. No loops checking if content is lost, the OS will tell you when to do your painting.


As discussed in Painting in AWT and Swing, this is the expected behavior when painting in AWT. In particular, a system-triggered painting operation occurs when a component is resized. As @rjacks notes, you need to dispose() any resources created in paint().

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜