我已经用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()有点疯狂;但是我不知道我应该多久使用一次。
任何帮助/指导将不胜感激。
答案 0 :(得分:1)
在上下文中没有可用代码的地方,您是否会重置变量hours
,min
,second
。
可以通过在数据周围放入一些打印语句以及状态的某些简单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);
}
}
}