简体   繁体   中英

How do I calculate the elapsed time from a Java Swing Timer

I have a Timer instance from javax.swing.Timer, I'm trying to calculate the time remaining from a cooldown because I'm using it for commands.

I'm testing it with a 15 second cooldown. The cooldown works fine but I want to be able to post how much time is remaining for when I get to larger cooldowns like 5 - 10 minutes etc. I want to say like 00:00:15 remaining 00:00:14 remaining 00:00:13 remaining etc

I know I'm missing something here.

Below I've put the code im using to calculate the elapsed time and the conversion from Millis to HMS When the command is called the start time is set to currentTimeMillis()

long startTime = System.currentTimeMillis();

public void callWithCooldown(int cooldown) {
        ActionListener callMethod = new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                enable();
            }
        };

        boolean didCall = call();
        if(!didCall) return;

        disable();
        this.timer = new Timer(cooldown, callMethod);
        timer.setRepeats(false);
        this.startTime = System.currentTimeMillis();
        timer.start();

        String notification = "Cooldown activated for " + MathHelper.millisecondsToHMS(cooldown) + "!";
        System.out.println(notification);
        notify(notification);
    }

public String elapsedTime() {
        long now = System.currentTimeMillis();
        long endTime = (startTime + cooldown);
        int elapsed = (int) (endTime - now);
        System.out.println(elapsed);
        return millisecondsToHMS(Math.abs(elapsed));
    }

    public static String millisecondsToHMS(int milliseconds) {
        String time = String.format("%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(milliseconds),
                TimeUnit.MILLISECONDS.toMinutes(milliseconds) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(milliseconds)),
                TimeUnit.MILLISECONDS.toSeconds(milliseconds) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(milliseconds)));
        return time;
    }

You can create two Timer objects. One for the total time waiting, and one for the count down:

import javax.swing.Timer;

public class Main {

    private static long START;

    public static void main(final String[] args) {
        final int totalSeconds = 15;

        final Timer tm = new Timer(1000, e -> {
            System.out.println("Seconds remaining: " + (totalSeconds * 1000 - System.currentTimeMillis() + START) / 1000d);
        });

        START = System.currentTimeMillis();

        new Timer(totalSeconds * 1000, e -> {
            tm.stop();
            System.out.println("Finished!");
        }).start();

        tm.start();

        //Wait for the program to execute:
        try { Thread.sleep((totalSeconds + 2) * 1000); } catch (final InterruptedException ix) {}
    }
}

Although I think Timer is not exactly the most accurate solution for such a problem (depending on how accurate you want it to be), but it is a simple one.

Or in your code, this could be:

import java.util.concurrent.TimeUnit;
import javax.swing.Timer;

public class Main {
    private long startTime;
    private final Timer total, countDown;

    public Main() {
        countDown = new Timer(1000, e -> System.out.println(elapsedTime()));
        total = new Timer(2000, e -> { //Defaults to 2000 ms for example.
            countDown.stop();
            enable();
        });
        total.setRepeats(false);
    }

    public void enable() {
        System.out.println("Enable!");
    }

    public void callWithCooldown(int cooldownSeconds) {
        total.setInitialDelay(cooldownSeconds * 1000);
        startTime = System.currentTimeMillis();
        total.start();
        countDown.start();
    }

    public String elapsedTime() {
        long now = System.currentTimeMillis();
        long endTime = (startTime + total.getInitialDelay());
        int elapsed = (int) (endTime - now);
        return millisecondsToHMS(Math.abs(elapsed));
    }

    public static String millisecondsToHMS(int milliseconds) {
        String time = String.format("%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(milliseconds),
                TimeUnit.MILLISECONDS.toMinutes(milliseconds) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(milliseconds)),
                TimeUnit.MILLISECONDS.toSeconds(milliseconds) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(milliseconds)));
        return time;
    }

    public static void main(final String[] args) {
        final int seconds = 15;
        new Main().callWithCooldown(seconds);
        //Let the program run for 'seconds' seconds at least to show all messages:
        try { Thread.sleep((seconds + 2) * 1000); } catch (final InterruptedException ix) {}
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM