【问题标题】:How do I calculate the elapsed time from a Java Swing Timer如何从 Java Swing Timer 计算经过的时间
【发布时间】:2020-04-23 11:20:15
【问题描述】:

我有一个来自 javax.swing.Timer 的 Timer 实例,我正在尝试计算冷却时间的剩余时间,因为我将它用于命令。

我正在测试它有 15 秒的冷却时间。冷却时间很好,但我希望能够发布当我进入更大的冷却时间(如 5 - 10 分钟等)时还剩多少时间。 我想说像 00:00:15 剩余时间 00:00:14 剩余时间 00:00:13 剩余时间 等等

我知道我在这里遗漏了一些东西。

下面我放了我用来计算经过时间和从 Millis 到 HMS 的转换的代码 调用命令时,开始时间设置为 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;
    }

【问题讨论】:

  • 真正的问题是什么?
  • 然后使用带有 1 秒 更新的计时器。
  • 我无法让它正确地告诉我还剩多少时间。理想情况下不需要使用第二个计时器
  • 经过的时间只是返回“剩余00:00:15!”转换为 HMS 后没有其他内容。
  • 请添加minimal reproducible example,包含输入、预期和观察到的输出。

标签: java swing time


【解决方案1】:

您可以创建两个Timer 对象。一个用于总等待时间,一个用于倒计时:

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) {}
    }
}

虽然我认为Timer 并不是此类问题的最准确解决方案(取决于您希望它有多准确),但它是一个简单的解决方案。

或者在您的代码中,这可能是:

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) {}
    }
}

【讨论】:

  • @DRAGONMASTER412 很高兴这是您要找的。​​span>
  • @DRAGONMASTER412 您也可以只使用一个计时器来执行此操作(例如,通过每 1 秒倒计时并添加一个计数器以达到 15)。但这会更不准确(因为从打印倒计时时间可以看出,在调用 Timer 的 Action 之间存在 2ms 的小增量延迟)。因此,例如 1 小时后(使用单个计时器),2ms/s 将达到 7200ms,依此类推。无论如何。
  • @DRAGONMASTER412 但是对于两个 Timers 方法,这种延迟是不正确的,因为 total 计时器会停止 countDown 一个。这两个计时器现在唯一的问题是,在 500 次调用之后的某个时刻,countDown 计时器会在打印语句中跳过整整一秒。这就是为什么我将剩余秒数的结果打印为浮点数而不是整数。
猜你喜欢
  • 2023-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-19
相关资源
最近更新 更多