JPanel does not wait for you to call repaint() when a change is made.
To prevent this, I think you can use RepaintManager as follows:-
RepaintManager.currentManager(yourJPanel).markCompletelyClean(yourJPanel)
There is another technique using two different JPanel instances. The basic idea is this:
- Set one visible and other invisible.
- Reflect the changes to the invisible (when invisible, panels does not update themselves)
- When you finish your game loop iteration switch their visibility and
start over
I don't know how the second one would affect the performance, though.