5

I want to have a clock showing current time and refreshes every second. The code I am using is:

int timeDelay = 1000;
ActionListener time;
time = new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent evt) {
            timeLabel.setText(DateTimeUtil.getTime()); 
            /*timeLabel is a JLabel to display time,
            getTime() is samll static methos to return formatted String of current time */
        }
    };
SwingWorker timeWorker = new SwingWorker() {

        @Override
        protected Object doInBackground() throws Exception {

            new Timer(timeDelay, time).start();
            return null;
        }
    };
timeWorker.execute();

What I want to refresh the timeLabel text in another thread other than EDT.
Am I doing it correct? Any other better way?
Also for information, i've added timeLabel to a extendedJPanel which contains few similar kinds of utilities, and is called in another MainJFrame.

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
Asif
  • 4,980
  • 8
  • 38
  • 53
  • 4
    In addition to the excellent advice from @Jonas (1+), one thing that you're doing wrong is making Swing calls from within a background thread. SwingWorker's `doInBackground()` method should contain no Swing calls that cannot be called on a background thread, meaning that you should most definitely not create a Swing Timer inside of this method, nor call `start()` on a Swing Timer object here. – Hovercraft Full Of Eels Mar 24 '12 at 20:14
  • +1 for this advice. Thank You. One more thing is, `doInBackground()` cannot contain Swing calls - is that mean I should not initializes swing components inside frame like panels, buttons etc via `SwingWorker`? – Asif Mar 24 '12 at 20:42
  • 2
    Absolutely correct. SwingWorker is for non-Swing initialization and for communication with Swing via publish, process, and done methods. – Hovercraft Full Of Eels Mar 24 '12 at 20:52

1 Answers1

14

You can do this without a SwingWorker, because this is what the Swing Timer is made for.

int timeDelay = 1000;
ActionListener time;
time = new ActionListener() {

    @Override
    public void actionPerformed(ActionEvent evt) {
        timeLabel.setText(DateTimeUtil.getTime()); 
        /* timeLabel is a JLabel to display time,
           getTime() is samll static methos to return 
           formatted String of current time */
    }
};

new Timer(timeDelay, time).start();
Jonas
  • 121,568
  • 97
  • 310
  • 388