【问题标题】:Java Countdown Timer reset issueJava倒数计时器重置问题
【发布时间】:2018-11-11 21:59:46
【问题描述】:

我在 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(); 有点疯狂但我不知道我应该多久使用一次哈哈。

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

【问题讨论】:

  • 你没有重置hours, min, second
  • 你在哪里重置hoursminsec
  • 我只想指出,这是一种幼稚的方法。 Swing Timer(甚至Thread.sleep)只保证“至少”持续时间。好的,所以它不是超高分辨率计时器,但您仍然需要了解这会导致“漂移”发生,尤其是在很长一段时间内。 “更好”的解决方案是计算自计时器启动以来经过的时间。幸运的是,Java 现在对此提供了很多支持 - for example

标签: java netbeans countdown


【解决方案1】:

没有你在哪里可用,脱离上下文,代码你重置变量hoursminsecond

这可以通过简单地在您的数据周围添加一些打印语句来解决,并且可能是您的状态的一些简单的desk check

话虽如此,这有点幼稚。

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

  }

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多