Начните с чтения Рисование в AWT и Swing и Выполнение пользовательской рисования , чтобы лучше понять, как на самом деле работает рисование в Swing.
Далеепрочитайте Параллельность в Swing , чтобы понять, как работает многопоточность в Swing.
paintComponent
должен отображать только текущее состояние компонента, он никогда не должен выполнять никаких операций, которые могут вызватьновый проход для рисования.
Поскольку paintComponent
можно вызывать в любое время по любым причинам, многие из которых вы не контролируете, попытка запланировать новый TimerTask
в нем - оченьочень, очень плохая идея.Вы можете получить любое количество таймеров, пытающихся внести изменения в пользовательский интерфейс, что приведет к снижению производительности и возможному конфликту друг с другом.
Поскольку Graphics
сам по себе также является временным, вы никогда не должны поддерживать ссылку наэто выходит за рамки paint
методов.
Сначала рассмотрим Как использовать Swing Timers для лучшего базового решения.Вы должны создать один Timer
, который обновляет состояние компонента и вызывает repaint
, который косвенно вызовет ваш paintComponent
, когда вы рисуете текущее состояние компонента.
Например,см. SnakeGame, как заставить хвост следовать за головой?