Каков наилучший способ работы с графическими контекстами AWT?
Вопрос
Некоторые пользователи нашего приложения Swing сообщили о странных артефактах, появляющихся на дисплее.Это варьируется от того, что компоненты не перекрашиваются должным образом в течение секунды или двух, вплоть до того, что целые части приложения перекрашиваются, как плиточные обои на участках окна.
Над приложением работали разработчики всех уровней - от опытных Java-специалистов до молодых парней сразу после окончания университета - в течение примерно пяти лет, и, как и следовало ожидать, часть AWT-кода представляет собой откровенный беспорядок.Сейчас передо мной стоит задача попытаться исправить как можно больше недостатков в течение следующих нескольких месяцев или около того.
С некоторыми из этих проблем легко справиться.Работайте с компонентами только в потоке отправки событий, ввод-вывод асинхронный и тому подобное, и я надеюсь донести это сообщение до остальной команды.
Что я хотел бы знать, так это лучший способ работы с графическими контекстами, особенно в контексте paintComponent().Я вижу очень много...
public void paintComponent( Graphics g ) {
super.paintComponent( g );
Graphics2D gfx = (Graphics2D)g;
// ...Whole lotta drawing code...
}
Лучше ли это делать на практике?
public void paintComponent( Graphics g ) {
super.paintComponent( g );
Graphics2D gfx = (Graphics2D)g.create();
// ...Whole lotta drawing code...
gfx.dispose();
}
Если параметр g будет повторно использоваться в других красках, то не нужно ли мне восстановить его в нормальное состояние, отменить AffineTransforms и т.д.?
Решение
По мнению Грязно Богатых Клиентов, вам не следует изменять Graphics
объект, переданный вам (что отстойно как API, IMO).
Правильный способ справиться с этим немного более подробный:
public void paintComponent(Graphics g1) {
super.paintComponent(g1);
final Graphics2D g = (Graphics2D)g1.create();
try {
// ...Whole lotta drawing code...
} finally {
g.dispose();
}
}
IIRC, в реализации Sun это не имеет значения, если вы не удаляете объекты "вспомогательной графики".(Не цитируйте меня по этому поводу.)
Возможно, вы захотите делегировать этот бит комментария другому объекту.
Другие советы
Я слышал, что это было исправлено в jdk-1.6.12, но не пробовал.