Java倒数计时器重置问题 [英] Java Countdown Timer reset issue

查看:82
本文介绍了Java倒数计时器重置问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经用Java编写了一个倒数计时器.它从用户在组合框中选择的任何数字开始递减计数,其中有3种(小时,分钟,秒).这部分工作正常.

I have coded a countdown timer in java. It counts down from whatever number a user selects in a combo box, there are 3 of them (hour, minute, second). This part is working perfectly fine.

当我按下重置"按钮时,问题就来了.它清除了我用来显示剩余时间的标签,并使它们显示为"00".但是,当我再次按开始键时,它会以秒为单位回想上次出现的位置,然后从那里开始.

The issue comes when I press my "Reset" button. It clears the labels I use to display the time left, and makes them display "00". But when I press start again, it recalls where it last was in terms of seconds left and starts there.

请帮助!

这是我的计时器代码:

private void JButtonActionPerformed(java.awt.event.ActionEvent evt) {                                        

    timer = new Timer(1000, new ActionListener(){


        @Override
        public void actionPerformed(ActionEvent e){

        onoff = true; 


        if(hours == 1 && min == 0 && sec ==0){

            repaint();
            hours--;
            lblHours.setText("00");
            min=59;
            sec=60;

        }

         if(sec == 0 && min <= 59 && min>0){   

             sec=60;
             min--;
             lblHours.setText("00");

         }

         if(sec == 0 && hours == 0 && min<=0){

             repaint();
             JOptionPane.showMessageDialog(rootPane, "You have run out of time and did not manage to escape!", "Time is up!!", 0 );
             hours = 0; min = 0; sec = 0;
             timer.stop();
         }

         else{

             sec--;
             repaint();

             if (sec<10){

             lblSeconds.setText("0"+sec);
             repaint();
             flag = false;

             }
             if (hours==0){

                 repaint();
                 lblHours.setText("00");

             if (min<10)

                 repaint();
                 lblMinutes.setText("0"+min);

                 if (sec<10)

                     lblSeconds.setText("0"+sec);

                 else

                     lblSeconds.setText(""+sec);


             }
             if(flag){
             lblHours.setText(""+hours);
             lblMinutes.setText(""+min);
             lblSeconds.setText(""+sec);
             repaint();

             }


         }
    }

});

    timer.start();


} 

我的重置按钮代码在这里:

And my code for the reset button is here:

    onoff =false;


    timer.stop();
    repaint();

    lblHours.setText("00");
    lblMinutes.setText("00");
    lblSeconds.setText("00");
    repaint();

我知道我对repaint()有点疯狂;但是我不知道我应该多久使用一次.

I know I go a bit crazy with the repaint(); but I have no idea how often I am meant to use it lol.

任何帮助/指导将不胜感激.

Any help/guidance would be greatly appreciated.

推荐答案

在上下文中没有可用的代码,您是否会重置代码 hours min .

No where in you available, out-of-context, code do you reset the variables hours, min, second.

可以通过在数据周围放置一些打印语句以及一些简单的

This could have been solved by simply putting in some print statements around your data and probably some simple desk check of your states.

话虽如此,这是一种幼稚的方法.

Having said that, this is some what of a naive approach.

摆动 Timer (甚至 Thread.sleep )仅保证至少"持续时间.

Swing Timer (and even Thread.sleep) only guarantee "at least" duration.

好的,因此您没有在开发超高分辨率计时器,但是您仍然需要了解,这可能导致漂移"的发生,尤其是在长时间内.

Okay, so you're not developing a super high-resolution timer, but you still need to understand that this can cause a "drift" to occur, especially over a large period.

更好"的解决方案是计算自计时器启动以来经过的时间.对我们来说幸运的是,Java现在以其更新的日期/时间API形式对此提供了很多支持.

A "better" solution would be to calculate the time passed since the timer was started. Lucky for us, Java now includes a lot of support for this in the form of its newer date/time API.

下面的示例使用一个简单的秒表"概念,该概念只是自启动以来经过的时间.它本身并不是实际的滴答声,因此非常有效.

The following example makes uses of a simple "stop watch" concept, which is simply the amount of time which has passed since it was started. It itself doesn't actual tick, making it very efficient.

但是向前移动的时钟将如何为您提供帮助?实际上很多.您可以计算剩余时间,但从当前经过的时间量(自启动以来)中减去所需的运行时间,就可以进行递减计数.很简单.

But how is a forward moving clock going to help you? A lot actually. You can calculate the time remaining but subtracting the desired run time from the current amount of time passed (since it was started) and you have a count down. Simple.

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.time.Duration;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
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 class StopWatch {

    private Instant startTime;
    private Duration totalRunTime = Duration.ZERO;

    public void start() {
      startTime = Instant.now();
    }

    public void stop() {
      Duration runTime = Duration.between(startTime, Instant.now());
      totalRunTime = totalRunTime.plus(runTime);
      startTime = null;
    }

    public void pause() {
      stop();
    }

    public void resume() {
      start();
    }

    public void reset() {
      stop();
      totalRunTime = Duration.ZERO;
    }

    public boolean isRunning() {
      return startTime != null;
    }

    public Duration getDuration() {
      Duration currentDuration = Duration.ZERO;
      currentDuration = currentDuration.plus(totalRunTime);
      if (isRunning()) {
        Duration runTime = Duration.between(startTime, Instant.now());
        currentDuration = currentDuration.plus(runTime);
      }
      return currentDuration;
    }
  }

  public static void main(String[] args) throws InterruptedException {
    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 JLabel label;
    private JButton btn;

    private StopWatch stopWatch = new StopWatch();
    private Timer timer;

    public TestPane() {
      label = new JLabel("...");
      btn = new JButton("Start");

      setLayout(new GridBagLayout());
      GridBagConstraints gbc = new GridBagConstraints();
      gbc.gridwidth = GridBagConstraints.REMAINDER;

      add(label, gbc);
      add(btn, gbc);

      timer = new Timer(500, new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
          Duration runningTime = Duration.of(10, ChronoUnit.MINUTES);
          Duration remainingTime = runningTime.minus(stopWatch.getDuration());
          System.out.println("RemainingTime = " + remainingTime);
          if (remainingTime.isZero() || remainingTime.isNegative()) {
            timer.stop();
            label.setText("0hrs 0mins 0secs");
          } else {
            long hours = remainingTime.toHours();
            long mins = remainingTime.toMinutesPart();
            long secs = remainingTime.toSecondsPart();
            label.setText(String.format("%dhrs %02dmins %02dsecs", hours, mins, secs));
          }
        }
      });
      timer.start();

      btn.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
          if (stopWatch.isRunning()) {
            stopWatch.pause();
            btn.setText("Start");
          } else {
            stopWatch.resume();
            btn.setText("Pause");
          }
        }
      });

    }

    @Override
    public Dimension getPreferredSize() {
      return new Dimension(200, 200);
    }

  }

}

这篇关于Java倒数计时器重置问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆