Reputation: 3
I want to execute an animation in an applet every time I click a button. The first time I click the button everything works fine. But the second time, the speed of the animation increases. The third time the speed of the animation increases a little bit more, and the fourth, and the fifth,...
I don´t know what is happening with the timer. How can i fix it?
In the applet I use this code:
JButton btnIniciar = new JButton("Iniciar");
btnIniciar.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
Timer timer = new Timer(50, new ActionListener(){
public void actionPerformed(ActionEvent e) {
//I have a list of packages to animate
for (Package p: listaPaquetes){
p.animate();
panel.repaint();
}
}
});
timer.start();
}
And this is the code of repaint in the panel:
protected void paintComponent(Graphics g) {
super.paintComponent(g);
//I use the same list of the applet
for (Package p: listaPaquetes){
//Paint the package
p.paintPackage(g);
}
}
This is how it works, the animation sends packages from left to right
Upvotes: 0
Views: 490
Reputation: 1152
When you press the button you are creating new javax.swing.Timer
and invoking timer.start()
which in this case is scheduled to run 50ms after the button press and repeat each 50ms.
When you press the button second time, you create and start another timer (a new one) which again works each 50ms with 50ms initial delay. You are now essentially doubling the number of repaint calls.
With third press you are tripling the number of repaint calls because you have 3 timers running.
If your button presses were timed properly it will look as if the speed has tripled (with 3 button presses).
If you do not want this behavior you can prevent the timer
to run if it is already running like this:
private Timer timer = null;
// ...
JButton btnIniciar = new JButton("Iniciar");
btnIniciar.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
// prevent the timer from running again if it is already running
if ( timer != null && timer.isRunning() ) return;
timer = new Timer(50, new ActionListener(){
public void actionPerformed(ActionEvent e) {
//I have a list of packages to animate
for (Package p: listaPaquetes){
p.animate();
panel.repaint();
}
}
});
timer.start();
}
Please note that you need to make timer
into an instance variable. Also you can replace the line:
if ( timer != null && timer.isRunning() ) return;
with
if ( timer != null ) return;
I simply wanted to show you that Timer
has isRunning()
method.
You can also stop the timer
by invoking timer.stop()
method.
Upvotes: 2