2
votes

I'm trying to implement a countdown timer into a pre-existing public class and I have a few questions.

An overview: I want to have a timer within a program that counts down from 60 (seconds) once the program is initialized.

If the timer reaches zero, the program quits.

If the user meets certain parameters within the 60 second time frame, the timer resets to 60, presents a new set of parameters, and begins the countdown again. It should be able to do this an infinite number of times, until the user fails to meet parameters within 60 seconds.

There will also be some sort of (TBD) GUI representation of the timer, most likely either numerical countdown or JProgressBar.

I'm semi-new (~3 months) to programming, self-taught, and still learning lots (so be gentle) :)

My questions are:

  1. What is the best way to implement this?

  2. I'm assuming this needs to run in a thread?

  3. Will the timer be easily configurable? (not important, just interesting)

Thanks for your help. If you need to see code, I can find some.

EDIT: Just for some clarification/context: This is for a timed racing video game I'm working on to develop my skills as a programmer. The idea is that a player has 60 seconds to complete a lap. If the player completes a successful lap, the timer resets to 60 seconds and the track changes to be slightly more difficult. The game runs until the player is unable to complete a lap in 60 seconds due to the difficulty. The game records the number of laps as a high score, and asks to player if they would like to try again.

4
Maybe instead of entirely exiting the program, you should just clear the frame, and display a message stating (something like) "Sorry, time's up!"? Programs that just mysteriously exit (even if there is a timer) would probably be considered buggy. Then just provide a "Reset" box on the menu. - Clockwork-Muse
Sorry, I didn't specify that in the description, but I was planning on having the program exit and display a JOptionPane that says something like "Sorry, the timer ran out! Click okay to try again." - Speakr
Then your program isn't really exiting, just the JFrame is being diabled or hidden (and a new one displayed). System.exit() will not work in that case; Have your main thread manage the windows, calling dispose() when the timer runs out (and re-initializing display elements from scratch, probably), and displaying the notification window. - Clockwork-Muse

4 Answers

1
votes

If I were you, I'd use:

  1. an AtomicInteger variable which would keep the current countdown value;
  2. a timer thread that would wake up every 1s and decrementAndGet() the variable, comparing the result to zero and terminating the app if the result is zero;
  3. (possibly) a thread that would also wake up every 1s to repaint the GUI -- the best approach here depends on your GUI framework.

Finally, whenever you need to reset the count back to 60s, you just call set(newValue) from any thread.

The timer thread's run() method could be as simple as:

for (;;) {
  if (counter.decrementAndGet() <= 0) {
    // TODO: exit the app
  }
  Thread.sleep(1000);
}

I think it's much easier to get this right than trying to manage multiple Timer objects.

0
votes

The best way to impliment timer in your application is using some sheduler frameworks like Quartz

0
votes

You could use java.util.Timer to schedule an execution of a method and then cancel it if the requirements is met.

Like this:

timer = new Timer();
timer.schedule(new Task(), 60 * 1000);

And then make a class like this to handle the timerschedule:

class Task extends TimerTask {
    public void run() {
      System.exit(0);
    }
  }

If the requirements is met, then do this to stop it from executing:

timer.cancel();
0
votes

If you need to update your GUI better to use SwingWorker http://en.wikipedia.org/wiki/SwingWorker I would write something like this:

SwingWorker<String, Integer> timer = new SwingWorker<String, Integer>() {
    Integer timer=60;
    @Override
    protected String doInBackground() throws Exception {
      //update guiModel
      //label.setText(timer.toString());
        while(timer>0){
        Thread.sleep(1000);
        timer--;
        }
        return null;
    }
    @Override
     public void done(){
         System.exit(0);
     } 
};

JButton restart = new JButton(){
    {
  addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                timer.cancel(true);
                timer.execute();
            }
        });      
    }
};