Принудительное полное обновление Java-апплета (AWT)

StackOverflow https://stackoverflow.com/questions/199152

Вопрос

У меня есть Java-апплет, который использует AWT.В некоторых (редких) случаях платформа не обновляет экран должным образом.Я могу переместить или свернуть / развернуть окно и убедиться, что мой апплет обновился должным образом.Я ищу код, который даст мне максимально полную перерисовку экрана апплета, имитирующую поведение минимизации / максимизации.

Я пробовал вызывать различные комбинации paint() / repaint() / invalidate() / update() для родительских контейнеров и выполнять рекурсию для различных дочерних элементов.Однако ни одна комбинация (которую я нашел) не устраняет ошибки фреймворка, с которыми я сталкиваюсь.Я ищу методы для полного обновления апплета, даже если они могут вызвать небольшое мерцание, поскольку я буду вызывать этот код только на проблемной платформе.

В моих тестах переход на Swing не помог решить мою проблему.

Кстати, это упрощение моего предыдущего (более сложного) поста: Java-апплет, проблема с обновлением AWT Mac OS X 10.4

Редактировать:Исследование в threading не решило эту проблему.Пометка "лучший ответ" как "хороший".

Это было полезно?

Решение

Это происходит постоянно, если вы не программируете внимательно в AWT / Swing.

Прежде всего, вы должны сделать ВСЕ работы с потоком событий. Это означает, что вы не можете сделать ничего из этого в своем основном утверждении (или что-то, что он вызывает напрямую). Я знаю, что каждое приложение Java с графическим интерфейсом пользователя когда-либо нарушало это правило, но это правило.

По большей части они говорили, что вы можете использовать не-awt-поток, пока окно не будет «реализовано». (pack / setVisible), но Sun понял, что это не всегда работает.

Во-вторых, когда вы получаете событие в потоке AWT, обязательно верните его быстро. Никогда не спите и не выполняйте долгую операцию.

В-третьих, (и это расширение "First"), если вы получаете обратный вызов, который НЕ находится в рабочем потоке AWT, обязательно поместите его в поток AWT, прежде чем делать что-либо с графическим интерфейсом.

Как правило, любое событие, генерируемое компонентом AWT, будет в правильном потоке. События, генерируемые таймерами, созданными вручную потоками или передаваемыми в main (), не являются.

Другие советы

Метод, который можно использовать для решения такого рода проблем, - это перекраска, как вы уже упоминали.Возможно, вы столкнулись с проблемой с JVM, которую вы используете.Я бы рекомендовал использовать разные версии Sun JVM и даже MS VM для IE, чтобы увидеть, связана ли это проблема с виртуальной машиной - на самом деле это может быть не связано с вашим кодом.

На самом деле я не пробовал этого раньше, но творческий подход (т.е.неприятный взлом) решением этой проблемы может быть выполнение javascript из апплета для вызова метода DOM для выполнения фиктивного изменения размера окна или, возможно, вызова фокуса на теле в попытке вызвать внешнее перерисовывание холста.

Не уверен, связано ли это с тем, что вы видели, но если вы столкнетесь с производительностью очереди событий AWT, мир java 2d + 3d (ребята из конвейера графики) укажет на многопоточную стратегию, и тогда вы ' Я попаду в проблему утилизации.

В этом обсуждении были рассмотрены проекты, использующие AWT Event Queue для графики, как при использовании " перекрасить " ;.

В многопоточном подходе существует проблема с отключением.

Примечания в java / awt / SequencedEvent для " утилизации " укажите нам на «Проблемы с потоками AWT» и " Автоотключение " ;.

Я думаю, что эта информация служит, по крайней мере, для решения проблемы.

Мне удалось исправить 99% проблем с перерисовкой апплета AWT, переключившись на Swing. Свинг кажется более надежным в освежении.

Раньше в коде моего апплета было много ручных перерисовок (), но с помощью Swing они были удалены, и теперь апплет работает быстрее, особенно в Terminal Server / LTSP.

Я поместил критические вещи в это:

public class VeryFastPanel extends JPanel {



    /**
         *
         */
        private static final long serialVersionUID = 1L;

        public void update(Graphics g) {

      paint(g);
    }

}

Я обнаружил, что проблема, похоже, та же, что и у вас. После некоторых тестов я обнаружил, что это может быть связано с адаптерами Aero и Intel Graphics. В моем случае приложение перестало перекрашиваться только при использовании в ноутбуках без адаптеров переменного тока, работающих от батарей. Если вы отключите некоторые функции энергосбережения в конфигурации драйвера Intel (в частности, Intel 2D Display Technology в старых выпусках драйверов), Java будет перекрашиваться в обычном режиме снова.

В моем случае я также нашел способы отключить эту опцию через реестр. Это не задокументировано, но работает.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top