Принудительное полное обновление Java-апплета (AWT) - PullRequest
1 голос
/ 14 октября 2008

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

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

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

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

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

Ответы [ 5 ]

2 голосов
/ 14 октября 2008

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

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

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

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

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

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

1 голос
/ 06 ноября 2009

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

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

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

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

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

1 голос
/ 14 октября 2008

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

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

0 голосов
/ 23 мая 2011

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

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

0 голосов
/ 14 октября 2008

Мне удалось исправить 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);
    }

}
...