Since you are moving a JLabel
, I would actually continue to use (a single) swing.Timer
. The reason for this is that the callback will always happen "on the EDT" and thus it is okay to access Swing components. (If you are using util.Timer
then the update should be posted/queued to the EDT, but this is a little more involved.)
Now, bear in mind that util.Timer
and swing.Timer
do not have guaranteed timings (other than "will be at least X long") and, to this end, it is important to account for the "time delta" (how long since it was since the last time the update occurred).
This is discussed in the article Fix Your Timestep! While the article was written about a simple game-loop and not a timer, the same concept applies. To get a consistent update pattern for a fixed velocity (no acceleration), simply use:
distance_for_dt = speed * delta_time
new_position = old_position + distance_for_dt
This will account for various fluctuations on a given system -- different system load, process contention, CPU power throttle, moon phase, etc. -- as well as make the speed consistent across different computers.
Once you are familiar with the basic position update, more "advanced" discrete formulas can be used for even more accurate positioning, including those that take acceleration into account.
Happy coding.
As BizzyDizzy poined out, System.nanoTime
can be used to compute the time-delta. (There are a few subtle issues with System.currentTimeMillis
and clock changes.)