0

I need to make a GUI where a worker enters a station (a spot on the panel) and stays there for a set amount of seconds, shown in a countdown about the workers head (so, once the workers moves to the spot, the station's label shows 3s -> 2s -> 1s and then the worker leaves, and the label reverts back to "OPEN"). I'm having trouble with making this happen, as I'm not too good with the Timer(s?) that Java has. I tried with something like this:

Timer timer = new Timer(1000, new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e)
        {
            //change label text/color, decrement countdown
            panel.repaint();
            Thread.sleep(1000);
        }
    });

But I can't reach the number of seconds to count down from from inside the timer, and I'm not sure how to pass that value to the timer. If someone can help me out, I'd really appreciate it.

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
user3622688
  • 61
  • 1
  • 8

2 Answers2

3

Get rid of the Thread.sleep(). That's what the 1000 in Timer(1000, new ActionListener() does. It sets an interval for each timer event. Every time a timer event is fired, the actionPerformed is called. So you need to determine what needs to happen every "tick", and put that code in the actionPerformed. Maybe something like

Timer timer = new Timer(1000, new ActionListener() {
    private int count = 5;
    @Override
    public void actionPerformed(ActionEvent e) {
        if (count <= 0) {
            label.setText("OPEN");
            ((Timer)e.getSource()).stop();
            count = 5;
        } else {
            label.setText(Integer.toString(count);
            count--;
        }
    }
});

You need to decide when to call timer.start().

Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
  • I did this and the countdown GUI part is working, but when I try to get the worker to stop while the countdown is occurring (by calling sleep(1000) for the second count), the countdown doesn't happen until my worker leaves. So the worker goes to the station, stops for 3secs, and when he leaves then the countdown starts on top of the station. Any idea how I can fix that? – user3622688 Nov 17 '14 at 05:52
  • Sorry, no idea what you're talking about. For better help, post [a Minimal, Complete, and Verifiable example](http://stackoverflow.com/help/mcve) – Paul Samsotha Nov 17 '14 at 05:55
1

Problem #1: You are calling Thread.sleep() from within the Swing GUI thread. That causes the thread to stop taking input and freeze. Delete that line. It does you no good! While you are at it, delete the repaint call as well.

Now that that's said and done, instead of creating an anonymous instance of ActionListener, you can create an actual class that implements ActionListener and provides a constructor. That constructor can have as an argument the number of seconds you want to start counting down. You can declare that class inside the method you are using, or you can declare it inside the class.

Here's a skeletal example:

public class OuterClass {
   JLabel secondsLabel = ...;
   Timer myTimer;

   private void setupTimer(int numSecondsToCountDown) {
      secondsLabel.setText(Integer.toString(numSecondsToCountDown));
      myTimer = new Timer(1000, new CountdownListener(numSecondsToCountDown));
      myTimer.start();
   }

   // ...
   class CountdownListener implements ActionListener {
      private int secondsCount;

      public CountdownListener(int startingSeconds) { secondsCount = startingSeconds; }

      public void actionPerformed(ActionEvent evt) {
         secondsLabel.setText(Integer.toString(secondsCount);
         secondsCount--;

         if (secondsCount <= 0) { // stop the countdown
            myTimer.stop();
         }
      }
   }
}
black panda
  • 2,842
  • 1
  • 20
  • 28