2

I need a timer for a game I am building and what it basically does is fire up an event that moves and object a square every second when I hit play. Now either I let the game take its course(the game finishes or the object moves out of bounds) or press play once again, the timer seems to be triggering the object to move faster than previously and so on, going faster and faster every time I restart the time.

    private void playButtonMouseClicked(java.awt.event.MouseEvent evt) {                                        
        /*code*/
        timer = new Timer(timerSpeed, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                /*code that ends with something that calls timer.stop()*/
            }
        }
    });
    if(timer.isRunning())   //in case I don't let the game stop the timer
        timer.stop();
    timer.start();
}

I checked with timer.getDelay() and the delay doesn't change, it stays the same, but I can see the arrow moving faster and faster every time. I'm using jPanels and a label with and icon to display the grid and the moving object.

Any ideas?

lukkes
  • 23
  • 5
  • 2
    For better help sooner, post a [MCVE] or [Short, Self Contained, Correct Example](http://www.sscce.org/). – Andrew Thompson Sep 10 '15 at 16:47
  • 1
    An unrelated issue, but I hope that you're not adding a MouseListener to a JButton, that you know that this should not be done, right? As for your main problem, I strongly second @AndrewThompson's recommendations -- let's see your [mcve] and see for ourselves why your code is not behaving properly. – Hovercraft Full Of Eels Sep 10 '15 at 16:52
  • 2
    My guess -- you're adding more and more MouseListeners to your button, when in fact you should be adding one single ActionListener to the JButton and only once. – Hovercraft Full Of Eels Sep 10 '15 at 16:54
  • The method playButtonMouseClicked is added on a jPanel actually, but why should I not add MouseListeners to a jButton? – lukkes Sep 10 '15 at 16:56
  • @Lucian I think the answers of [this question](http://stackoverflow.com/q/13526555/4857909) are pretty good explanations. – Lukas Rotter Sep 10 '15 at 17:00
  • Alright, @LuxxMiner, that does answer my question about using MouseListeners in a clear way, thank you. – lukkes Sep 10 '15 at 17:03
  • @HovercraftFullOfEels I'm not sure I understand your point. Where exactly am I adding more and more MouseListeners to the button? – lukkes Sep 10 '15 at 17:05
  • 5
    Don't create a new Timer object every time you click the button. The Timer object should be created in the constructor of your class. Then you just start/stop the Timer as required. Maybe you have a bug in your code that doesn't stop the Timer as you expect, so then next time you click the button you have multiple Timers running. – camickr Sep 10 '15 at 17:07
  • 2
    @Lucian He just guessed ("*My guess..."*) - He can't know as long as you don't post a [mcve]. (Therefore he probably can't exactly tell you where you are adding more mouselisteners (if you are)). – Lukas Rotter Sep 10 '15 at 17:08
  • The [docs](http://docs.oracle.com/javase/7/docs/api/java/util/Timer.html) for timer say that timers can actually "bunch up" and execute rapidly. Maybe that could be the issue that your seeing. I'd go with the solution @camickr provided. – Bryan Herrera Sep 10 '15 at 17:10
  • 2
    Like @camickr commented above, I was creating a new Timer object every time I clicked my button, which was the cause of my problem. I removed the `timer = new Timer(timerSpeed, new ActionListener()` part from my code and initialized the timer in the constructor instead, adding the action listener as well, then I just restarted the timer in my method like I was before. Thank you for your help, but you are welcome to write the solution as an answer so that you can take credit for it. – lukkes Sep 10 '15 at 17:33

1 Answers1

6

but I can see the arrow moving faster and faster every time.

This tells me you have multiple Timers executing.

Your current code creates a new Timer every time the button is clicked.

The timer.isRunning() check will never be true because you just created a new Timer which will not be running since you haven't started it yet.

So your old Timer may still be running but because you no longer have a reference to it, you can't stop it.

The solution:

Don't create a new Timer object every time you click the button. The Timer object should be created in the constructor of your class. Then you just start/stop the Timer as required

camickr
  • 321,443
  • 19
  • 166
  • 288