0

I have a milliseconds and i convert it hh:mm:ss now i want to make it to automatically decrease value overtime.. something like countdown timer

for example, when user sees it, 2:11 0 -> 2:10 59 -> 2:10 58 ...

Below is my code..

        Timer t = new Timer(1000, new ActionListener() {
            public void actionPerformed(ActionEvent e) {

                int s = ((TIMER/1000) % 60);
                int m = (((TIMER/1000) / 60) % 60);
                int h = ((((TIMER/1000) / 60) /60) % 60);

                timing.setText(hour + " hours, " + min + " minutes" + sec + " seconds");
                timing.repaint();
}
}
t.start();

is it possible?

SOer
  • 139
  • 1
  • 7
  • 13

4 Answers4

1
final Timer t = new Timer(1000, new ActionListener() {
    private long time = 10 * 1000; //10 seconds, for example

    public void actionPerformed(ActionEvent e) {
        if (time >= 0) {
            long s = ((time / 1000) % 60);
            long m = (((time / 1000) / 60) % 60);
            long h = ((((time / 1000) / 60) / 60) % 60);
            timing.setText(h + " hours, " + m + " minutes " + s + " seconds");
            time -= 1000;
        }
    }
});
t.start();
dogbane
  • 266,786
  • 75
  • 396
  • 414
1

As Peter mentioned in his answer, you shouldn't relay on decreasing a number, since there are not guarantees that actionPerformed is invoked right in every second. The below is a working example, which stops the timer on finishing (detailed and therefor code):

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Test extends JFrame {
  private JTextField text;
  private Timer timer;
  private JButton start;

  public Test() {
    super("Countdown timer");
    text = new JTextField("2", 8);
    start = new JButton("Start");
    start.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent click) {
        final long current = System.currentTimeMillis();
        try {
          final long limit = Integer.parseInt(text.getText().trim())* 1000; // X seconds
          timer = new Timer(1000, new ActionListener() {
            public void actionPerformed(ActionEvent event) {
              long time = System.currentTimeMillis();
              long passed = time - current;
              long remaining = limit - passed;
              if(remaining <= 0) {
                text.setText("2");
                timer.stop();
              } else {
                long seconds = remaining/1000;
                long minutes = seconds/60;
                long hours = minutes/60;
                text.setText(String.format("%02d:%02d:%02d", hours, minutes, seconds%60));
              }
            }
            });
          timer.start();
        } catch(NumberFormatException nfe) {
          // debug/report here
          nfe.printStackTrace();
        }
      }});
    JPanel panel = new JPanel();
    panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
    panel.add(text);
    panel.add(new JLabel(" seconds"));
    panel.add(start);
    add(panel);
  }

  public static void main(String [] args) throws Exception {
    Test frame = new Test();
    frame.setDefaultCloseOperation(Test.EXIT_ON_CLOSE);
    frame.pack();
    frame.setVisible(true);
  }
}
khachik
  • 28,112
  • 9
  • 59
  • 94
0

The TIMER value is never decremented by the timer event. Therefore the same time will always be displayed every 1000 milliseconds.

Edit: Assuming "timing" is a Swing component the call to repaint should be unnecessary.

Tansir1
  • 1,789
  • 2
  • 15
  • 28
  • how do i do it? i am new to java – SOer Nov 30 '10 at 14:37
  • Assuming TIMER is a numeric type, TIMER -= 1000; should do it. http://download.oracle.com/javase/tutorial/java/nutsandbolts/op1.html Here are some more references on Java's various timers: http://java.sun.com/products/jfc/tsc/articles/timer/ and http://download.oracle.com/javase/tutorial/uiswing/misc/timer.html – Tansir1 Nov 30 '10 at 14:44
0

A safer option is to take the actual clock time. The reason for this is that your application can stop for pewriods of time. esp if you machine is busy. This means a countdown timer might not be called as often as you expect. If you use the System.currentTimeMillis() the time will always be right no matter what happens.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130