Java倒数计时器重置问题

时间:2018-11-11 21:59:47

标签: java netbeans countdown

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

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

请帮助!

这是我的计时器代码:

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();


} 

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

    onoff =false;


    timer.stop();
    repaint();

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

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

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

1 个答案:

答案 0 :(得分:1)

在上下文中没有可用代码的地方,您是否会重置变量hoursminsecond

可以通过在数据周围放入一些打印语句以及状态的某些简单desk check来解决此问题。

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

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

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

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

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

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

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

  }

}