5

I'm a Java beginner and I'm trying to build a simple stopwatch program that displays the time on a swing GUI. Making the stopwatch is easy, however I cannot find a way to make the GUI update every second and display the current time on the stopwatch. How can I do this?

Dangerosking
  • 438
  • 3
  • 12
  • 23
  • 10
    Use `Swing`'s `Timer` class. More on the way of using the `Timer` is available, for example, [in the question and particularly answers to it.](http://stackoverflow.com/q/11053097/613495) – Boro Jun 15 '12 at 21:06
  • 3
    See also this [answer](http://stackoverflow.com/a/5529043/230513). – trashgod Jun 15 '12 at 21:13
  • Yea I know I had it somewhere [one of my answers related to use of `Timer`](http://stackoverflow.com/a/5911514/613495). @trashgod very nice answer/sample +1 here and +1 there... and I am out of votes ... for today :) – Boro Jun 15 '12 at 21:32
  • @trashgod Just had a look to your answer, it looks far more better then mine. I will just delete my answer below :) – GETah Jun 15 '12 at 21:51
  • 1
    Please have a glance at this [example](http://stackoverflow.com/questions/9907583/set-dynamic-jlabel-text-in-a-jdialog-by-timer/9908342#9908342) code too :-) – nIcE cOw Jun 16 '12 at 01:20

1 Answers1

6

Something along these lines should do it:

import java.awt.EventQueue;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JFrame;
import javax.swing.JLabel;

/** @see https://stackoverflow.com/a/11058263/230513 */
public class Clock {

    private Timer timer = new Timer();
    private JLabel timeLabel = new JLabel(" ", JLabel.CENTER);

    public Clock() {
        JFrame f = new JFrame("Seconds");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(timeLabel);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
        timer.schedule(new UpdateUITask(), 0, 1000);
    }

    private class UpdateUITask extends TimerTask {

        int nSeconds = 0;

        @Override
        public void run() {
            EventQueue.invokeLater(new Runnable() {

                @Override
                public void run() {
                    timeLabel.setText(String.valueOf(nSeconds++));
                }
            });
        }
    }

    public static void main(String args[]) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                final Clock clock = new Clock();
            }
        });
    }
}

The timeLabel will always display the number of seconds the timer has been running.

  1. You will need to correctly format it to display "hh:mm:ss"; one approach is shown here.

  2. Create a container and add the label to it so that you can display it as part of the GUI.

  3. Compare the result to this alternate using javax.swing.Timer.

Community
  • 1
  • 1
GETah
  • 20,922
  • 7
  • 61
  • 103
  • I made the GUI using the visual editor from netbeans, how can I reference a jlabel inside the GUI? – Dangerosking Jun 15 '12 at 21:26
  • @trashgod which part needs an invokeLater? – GETah Jun 15 '12 at 21:38
  • @GETah The `run()` method of `UpdateUITask`, since a java.util.Timer will run it off the EDT. – millimoose Jun 15 '12 at 21:40
  • (Also, a `ScheduleExecutorService` would probably the more modern equivalent to a `java.util.Timer` to begin with, if only to use the same API anywhere you need to have background tasks running.) – millimoose Jun 15 '12 at 21:43
  • @trashgod Thanks for the updates ;) +1 for you answer on the other related question ;) – GETah Jun 16 '12 at 08:48