5

I created a game and in my swing GUI interface I want to put a timer. The way I do this at the moment is have a field with the current time , gotten with System.currentTimeMillis() which gets it's value when the game starts .In the method of my game i put the System.currentTimeMillis()- field; and it tells you the current time passed since the game started.

Nevertheless, how do get this to update itself every second lets say, so the JLabel will have : timePassed: 0s , timePassed: 1s and so on. Have in mind that i don't use threads in my game at any point.

EDIT: thank you all for your kind suggestions. I used a combination of your answers please give me some feedback.

I have the JLabel as a field called time. (else i cant handle it).

time = new JLabel("Time Passed:  " + timePassed() + " sec");
panel_4.add(time);

ActionListener actionListener = new ActionListener() {
    public void actionPerformed(ActionEvent actionEvent) {
        time.setText("Time Passed: " + timePassed() + " sec");
    }
};

Timer timer = new Timer(1000, actionListener);
timer.start();
Dan
  • 324
  • 1
  • 3
  • 13
Martinos
  • 167
  • 1
  • 2
  • 9
  • 2
    The answer is in the question. Look at http://download.oracle.com/javase/6/docs/api/javax/swing/Timer.html – JB Nizet May 29 '11 at 15:16
  • 1
    if you use Swing, then you do use threads. You can't possibly do everything just in the EDT! – jfpoilpret May 29 '11 at 15:39
  • err.. yes i can :P my gui is used to navigate from one display to another, i.e. main menu to the play screen to the options screen etc. Although 2 or 3 windows can stay open at any given time, i will never have a use for a window to be duplicate. So what is the problem? – Martinos May 29 '11 at 18:15
  • your updated code looks good. Yep, the JLabel needs to be held in a variable for this to work, either a final local variable or a non-static class field. My only critique is that one should strive to avoid use of "magic numbers", here the 1000. Use a constant for this, so you can more easily change it if need be in the future. – Hovercraft Full Of Eels May 29 '11 at 19:08

4 Answers4

6

Have a look at the swing timer class. It allows to setup recurring tasks quite easily.

Howard
  • 38,639
  • 9
  • 64
  • 83
5

This is how I would set my JLabel to update with time & date.

Timer SimpleTimer = new Timer(1000, new ActionListener(){
    @Override
    public void actionPerformed(ActionEvent e) {
        jLabel1.setText(SimpleDay.format(new Date()));
        jLabel2.setText(SimpleDate.format(new Date()));
        jLabel3.setText(SimpleTime.format(new Date()));
    }
});
SimpleTimer.start();

This is then added to your main class and the jlabel1/2/3 get updated with the timer.

dario
  • 5,149
  • 12
  • 28
  • 32
  • 1
    @gcclinux what do you mean by SimpleDay, SimpleTime ?!, they are variables or classes ? – asma Nov 27 '19 at 00:24
4
new Thread(new Runnable
{
    public void run()
    {
        long start = System.currentTimeMillis();
        while (true)
        {
            long time = System.currentTimeMillis() - start;
            int seconds = time / 1000;
            SwingUtilities.invokeLater(new Runnable() {
                 public void run()
                 {
                       label.setText("Time Passed: " + seconds);
                 }
            });
            try { Thread.sleep(100); } catch(Exception e) {}
        }
    }
}).start();
Martijn Courteaux
  • 67,591
  • 47
  • 198
  • 287
  • Never access Swing components (`label.setText(...)`) outside the EDT! – jfpoilpret May 29 '11 at 15:37
  • @jfpoilpret: What is the alternative? How to make it work without locking the EDT with your label updater loop. – Martijn Courteaux May 29 '11 at 15:41
  • @Martinos: go with the Swing timer recommendation by Howard. While Marijn means well, his answer is not recommended. – Hovercraft Full Of Eels May 29 '11 at 15:42
  • 2
    @Martijn: the Swing timer takes care of looping (it uses a background thread behind the scenes), and has the advantage that all code in the actionPerformed block is called on the EDT. If a background thread must be directly used, it's convenient to use a SwingWorker to help ensure that Swing code is called on the EDT. If you can't use a SwingWorker then you must take care to queue all Swing code on the EDT via `SwingUtilities.invokeLater(myRunnable);` – Hovercraft Full Of Eels May 29 '11 at 15:54
  • @Martijn: yes, much. -1 removed, +1 added. – Hovercraft Full Of Eels May 29 '11 at 16:36
  • ok here is the answer i did please give me feedback(look at my edit) – Martinos May 29 '11 at 18:17
  • 1
    @Martijn, the code is bad: no exit of the loop what so ever, at least test: `if (!label.isDisplayable())`... – bestsss May 29 '11 at 20:19
  • @Hovercraft, also it doesn't compile but i thought that was obvious – bestsss May 29 '11 at 20:34
0

wirite this in Constructor

ActionListener taskPerformer = new ActionListener() {

             @Override

            public void actionPerformed(ActionEvent evt) {
               jMenu11.setText(CurrentTime());
            }
        };

        Timer t = new Timer(1000, taskPerformer);
        t.start();

And this Write out Constructor

public String CurrentTime(){

       Calendar cal = new GregorianCalendar();
       int second = cal.get(Calendar.SECOND);
       int min = cal.get(Calendar.MINUTE);
       int hour = cal.get(Calendar.HOUR);
       String s=(checkTime(hour)+":"+checkTime(min)+":"+checkTime(second));
       jMenu11.setText(s);
       return s;

   }

   public String checkTime(int t){
String time1;
if (t < 10){
    time1 = ("0"+t);
    }
else{
    time1 = (""+t);
    }
return time1;

}