Джава;краска (графика) вызывается слишком много после изменения размера окна! - PullRequest
0 голосов
/ 22 июня 2011

У меня есть вопрос. Недавно я искал способы реализации аппаратного рендеринга с использованием 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 голосов
/ 22 июня 2011

Я действительно не думаю, что у вас должен быть цикл в вашем методе рисования.Он должен рисовать один раз для каждого действия, которое требует рисования, а затем возвращаться. Когда вы перетаскиваете экран, OS / env позаботится о повторной отправке сообщений перерисовки в ваше приложение.Вы должны перекрасить, если это возможно, а затем просто вернуться.Никаких циклов, проверяющих, потерян ли контент, ОС сообщит вам, когда рисовать.

0 голосов
/ 22 июня 2011

Как обсуждено в Рисование в AWT и Swing , это ожидаемое поведение при рисовании в AWT.В частности, инициируемая системой операция рисования происходит при изменении размера компонента.Как отмечает @rjacks, вам нужно dispose() любые ресурсы, созданные в paint().

0 голосов
/ 22 июня 2011

Причина, по которой вы получаете исключение OutOfMemoryException, заключается в том, что вы никогда не очищаете свой VolatileImage. Как я понимаю, вы выделяете новый VolatileImage каждый раз, когда вызывается paint(), что может происходить много сотен (или в вашем случае более тысячи) раз в секунду. Если вы не освободите память, используемую VolatileImage, или не исправите ситуацию, чтобы выделить один раз , а не один раз за кадр, пространство памяти вашего приложения будет увеличиваться до тех пор, пока не произойдет сбой JVM. Попробуйте добавить вызов к offscreengraphics.dispose() в конце цикла рендеринга. Также прочитайте Javadoc .

EDIT:

Еще одна полезная ссылка .

...