How to Make a Countdown Timer in Java

How to make a countdown CountDown Timer in java ( stopwatch Java )

package com.test;

import java.util.Scanner;
import java.util.Timer;
import java.util.TimerTask;

public class StopWatch
{
public static int interval;

public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Input seconds => : ");
interval = input.nextInt();
int delay = 1000;
int period = 1000;
final Timer time = new Timer();
System.out.println(interval);
time.scheduleAtFixedRate(new TimerTask() {

public void run() {
if (interval == 0) {
System.out.println("work finished");
time.cancel();
time.purge();
} else {
System.out.println(setInterval());
}
}
}, delay, period);
}

private static int setInterval() {

return --interval;
}

}

How to make count down timer in Java?

You maybe do like this:

package com.example;

import java.util.Timer;
import java.util.TimerTask;

public class MyTimer {

public static void main(String[] args) {
Timer timer = new Timer();
timer.schedule(new App(), 0, 1000);
}
}

class App extends TimerTask {

int countdown = 100;

public void run() {
countdown = countdown - 1;
System.out.println(countdown);
//label.setText(countdown +"second's left");
}

}

// Result:
//99
//98
//97
//96
//95
//94

It just works. Change System.out.println(countdown); by label.setText(countdown +"second's left"); as what you want.

Reference

http://docs.oracle.com/javase/8/docs/api/index.html?java/util/TimerTask.html

http://docs.oracle.com/javase/8/docs/api/index.html?java/util/Timer.html

Java countdown timer minutes and seconds

You need to display remaining number of second i in format mimutes:seconds format. If you assume that there are always 60 seconds in a minute:

String time = String.format("%02d:%02d", i / 60, i % 60);
System.out.println(time);

create a java gui countdown timer that starts with user input

So, the basic idea is to start with a Swing Timer. It's safe to use it to update the UI, won't block the UI thread and can repeat at a regular interval. See How to use Swing Timers for more details.

Because all timers only guarantee a minimum duration (that is, they could wait longer then the specified delay), you can't rely on updating a state value simply by adding the expected duration. Instead, you need to be able to calculate the difference in time between to points in time.

For this, I would use the Date/Time API introduced in Java 8. See Period and Duration and Date and Time Classes for more details.

From there, it's a simple matter of setting up a Timer, calculating the Duration from the start time to now and formatting the result

import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.time.Duration;
import java.time.LocalDateTime;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

public static void main(String[] args) {
new Test();
}

public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}

JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}

public class TestPane extends JPanel {

private LocalDateTime startTime;
private JLabel label;
private Timer timer;

public TestPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(2, 2, 2, 2);
gbc.gridwidth = GridBagConstraints.REMAINDER;

label = new JLabel("...");
add(label, gbc);

JButton btn = new JButton("Start");
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (timer.isRunning()) {
timer.stop();
startTime = null;
btn.setText("Start");
} else {
startTime = LocalDateTime.now();
timer.start();
btn.setText("Stop");
}
}
});
add(btn, gbc);

timer = new Timer(500, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
LocalDateTime now = LocalDateTime.now();
Duration duration = Duration.between(startTime, now);
label.setText(format(duration));
}
});
}

protected String format(Duration duration) {
long hours = duration.toHours();
long mins = duration.minusHours(hours).toMinutes();
long seconds = duration.minusMinutes(mins).toMillis() / 1000;
return String.format("%02dh %02dm %02ds", hours, mins, seconds);
}

}

}

Countdown timer...

This timer counts up. How would I get it to count down instead? I tried putting in code from your links but it wouldn't work. The documentations didn't help me understand much either.

This requires a slightly better understanding of the Date/Time API.

Basically, you need to know the expected duration (how long the timer should run for) and the amount of time the timer has been running. From this, you can calculate the amount of time remaining (the countdown)

For simplicity, I started with a Duration of 5 minutes...

private Duration duration = Duration.ofMinutes(5);

Each time the Timer ticked, I simply calculated the running time and calculate the remaining time...

LocalDateTime now = LocalDateTime.now();
Duration runningTime = Duration.between(startTime, now);
Duration timeLeft = duration.minus(runningTime);
if (timeLeft.isZero() || timeLeft.isNegative()) {
timeLeft = Duration.ZERO;
// Stop the timer and reset the UI
}

All I really did was played around with the API. I knew I would need a Duration in the end (as that's what I was formatting) so I wanted to keep that. Since I also needed a "duration" of time, to represent the length of time the Timer should run for, the Duration class seemed like a good place to start.

I had thought I might need to calculate the difference between the two Durations (like I did for the runningTime), but as it turns out, all I really wanted was the difference between them (ie subtraction of one from the other).

All that was left was to add a check to ensure that the Timer doesn't run into negative time and you know have a concept of a "time out" or "count down" timer.

When you're dealing with these kinds of problems, its always a good thing to start out with a "core concept" of how it "might" work - ie, start by figuring out how you might count down in seconds. This gives you some ground work, from there, you can see what support the API provides and how you might use it to your advantage. In this case, Duration was super easy and continued to provide support for the formatting of the output

For example...

import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.time.Duration;
import java.time.LocalDateTime;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

public static void main(String[] args) {
new Test();
}

public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}

JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}

public class TestPane extends JPanel {

private LocalDateTime startTime;
private JLabel label;
private Timer timer;

private Duration duration = Duration.ofMinutes(5);

public TestPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(2, 2, 2, 2);
gbc.gridwidth = GridBagConstraints.REMAINDER;

label = new JLabel("...");
add(label, gbc);

JButton btn = new JButton("Start");
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (timer.isRunning()) {
timer.stop();
startTime = null;
btn.setText("Start");
} else {
startTime = LocalDateTime.now();
timer.start();
btn.setText("Stop");
}
}
});
add(btn, gbc);

timer = new Timer(500, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
LocalDateTime now = LocalDateTime.now();
Duration runningTime = Duration.between(startTime, now);
Duration timeLeft = duration.minus(runningTime);
if (timeLeft.isZero() || timeLeft.isNegative()) {
timeLeft = Duration.ZERO;
btn.doClick(); // Cheat
}

label.setText(format(timeLeft));
}
});
}

protected String format(Duration duration) {
long hours = duration.toHours();
long mins = duration.minusHours(hours).toMinutes();
long seconds = duration.minusMinutes(mins).toMillis() / 1000;
return String.format("%02dh %02dm %02ds", hours, mins, seconds);
}

}

}

Java Timer Countdown from certain time

Don't use Date or Calendar, the java.time API is more the capable of achieving what you want.

Looking at this...

Date date = new Date();
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH);
int day = calendar.get(Calendar.DAY_OF_MONTH);

//creating a new calendar with all of the data
Calendar cal = Calendar.getInstance();
cal.set(year, month, day, hours, mins, seconds);

You're creating a new time, based on the hours/mins/seconds, but, what worries me is, is what happens if the time is less than now? This "might" be the issue you're having.

So, some thing you might want to do is verify if the time is before or after the current time and roll the day accordingly - assuming you want to use an absolute time (ie create a timer which counts down from now to 6pm)

This...

Duration countingDown = Duration.between(Instant.now(), userInputCountDown);

also seems off to me, as userInputCountDown should be in the future

The following example takes a slightly different approach, as it creates a "timer" that will create a target in the future (based on the input) from the current time (adding the hours, mins and seconds) and use it as the anchor point for the count down.

So, you might say, "create a 1 hour" timer, for example.

import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.Timer;

class Main {

public static void main(String[] args) {
new Main();
}

public Main() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}

public class TestPane extends JPanel {

private JTextField targetHours;
private JTextField targetMins;
private JTextField targetSeconds;

private Instant futureTime;
private Timer timer;

private JLabel countDown;

public TestPane() {

setLayout(new GridBagLayout());

targetHours = new JTextField("00", 2);
targetMins = new JTextField("00", 2);
targetSeconds = new JTextField("00", 2);

JPanel targetPane = new JPanel(new GridBagLayout());
targetPane.add(targetHours);
targetPane.add(new JLabel(":"));
targetPane.add(targetMins);
targetPane.add(new JLabel(":"));
targetPane.add(targetSeconds);

GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.insets = new Insets(8, 8, 8, 8);

add(targetPane, gbc);

JButton btn = new JButton("Start");
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
futureTime = LocalDateTime.now()
.plusHours(Long.parseLong(targetHours.getText()))
.plusMinutes(Long.parseLong(targetMins.getText()))
.plusSeconds(Long.parseLong(targetSeconds.getText()))
.atZone(ZoneId.systemDefault()).toInstant();

if (timer != null) {
timer.stop();
}

countDown.setText("---");
timer = new Timer(500, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Duration duration = Duration.between(Instant.now(), futureTime);
if (duration.isNegative()) {
timer.stop();
timer = null;
countDown.setText("00:00:00");
} else {
String formatted = String.format("%02d:%02d:%02d", duration.toHours(), duration.toMinutesPart(), duration.toSecondsPart());
countDown.setText(formatted);
}
}
});
timer.start();
}
});

add(btn, gbc);

countDown = new JLabel("---");
add(countDown, gbc);
}

}

}

WARNING - I do NO validation on the input, so you will have to be careful.

If, instead, you wanted to count down to a particular point in time (ie count down from now to 6pm), then you would need to use LocalDateTime#withHour(Long)#withMinute(Long)#withSecond(Long) chain instead. But, beware, you'll have to verify if the time is in the future or past and take appropriate action, because if you want to countdown to 6pm, but it's 7pm ... what does that actually mean :/ ?

Creating a count down timer- Java

Each time your timer runs, it performs the loop from 0 to 30, thus the UI is refreshed only when the loop ends. You need to keep your i in a member and update it each time the run method is called as such:

    Timer timer = new Timer();

TimerTask task = new TimerTask(){
private int i = 0;
public void run(){
if (i <= 30) {
lblTimer.setText("" + i++);
}
}
};
timer.scheduleAtFixedRate(task, 0, 1000); //1000ms = 1sec

Of course once your reach i = 30, you should cancel your times, otherwise it'll still run every second but with no real effect or need.

How to Show Countdown timer in HH:MM:SS (Hours : Minutes : Seconds)

It's helpful for you

 private void startTimer(int noOfMinutes) {
CountDownTimer countDownTimer = new CountDownTimer(noOfMinutes, 1000) {
public void onTick(long millisUntilFinished) {
long millis = millisUntilFinished;
//Convert milliseconds into hour,minute and seconds
String hms = String.format("%02d:%02d:%02d",
TimeUnit.MILLISECONDS.toHours(millis),
TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)), TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)));
countdownTimerText.setText(hms);//set text
}
public void onFinish() {
countdownTimerText.setText("TIME'S UP!!"); //On finish change timer text
}
}.start();

Edited

//1584700200 is timestamp in milii seconds (Friday, March 20, 2020 10:30:00 AM) 
//1000(1sec) is time interval to call onTick method

new CountDownTimer(1584700200, 1000){

@Override

public void onTick(long millisUntilFinished) {
long millis = millisUntilFinished;
String hms = String.format("%02d:%02d:%02d:%02d",
TimeUnit.HOURS.toDays(TimeUnit.MILLISECONDS.toHours(millis)),
(TimeUnit.MILLISECONDS.toHours(millis) -
TimeUnit.DAYS.toHours(TimeUnit.MILLISECONDS.toDays(millis))),
(TimeUnit.MILLISECONDS.toMinutes(millis) -
TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis))), (TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis))));
countdownTimerText.setText(hms);//set text
}

@Override

public void onFinish() {
/*clearing all fields and displaying countdown finished message */

countdownTimerText.setText("Count down completed");
}
}.start();
}

Kotlin

private fun countDown() {
val countDownTimer = object : CountDownTimer(1584700200, 1000) {
override fun onTick(p0: Long) {
val millis: Long = p0
val hms = String.format(
"%02d:%02d:%02d:%02d",
TimeUnit.HOURS.toDays(TimeUnit.MILLISECONDS.toDays(millis)),
(TimeUnit.MILLISECONDS.toHours(millis) - TimeUnit.DAYS.toHours(
TimeUnit.MILLISECONDS.toDays(
millis
)
)),
(TimeUnit.MILLISECONDS.toMinutes(millis) -
TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis))),
(TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(
TimeUnit.MILLISECONDS.toMinutes(millis)
))
)

System.out.println("Time : " + hms)
countdownTimerText.setText(hms);//set text
}

override fun onFinish() {
/*clearing all fields and displaying countdown finished message */
countdownTimerText.setText("Count down completed");
System.out.println("Time up")
}
}
countDownTimer.start()
}


Related Topics



Leave a reply



Submit