将恢复功能添加到秒表 [英] Adding resume function to stopwatch
问题描述
我编写了一个带有三种功能的简单秒表。首先,我有一个开始秒表的开始按钮,一个用于暂停秒表的暂停按钮,以及一个用于重置整个秒表的重置按钮。
I have programmed a simple stopwatch with three functionalities. First, I have a start button to begin the stopwatch , a pause button to pause the stopwatch and finally a reset button to reset the entire stopwatch.
当我点击暂停按钮时,秒表暂停,比如说10.0秒。当我恢复秒表(再次按下开始按钮)时,秒表不会从10.0秒开始恢复。它从我暂停的时间和当前时间恢复。例如,如果我暂停5秒钟并且恢复恢复,秒表将从15.0秒开始。
When I hit the pause button, the stopwatch pauses, say at 10.0 seconds. When I resume the stopwatch (pressing the Start button again), the stopwatch doesn't resume from 10.0 seconds onwards. It resumes from the amount of time I paused and the current time. For example, if I paused for 5 seconds and hit resume, the stopwatch goes from 15.0 seconds onwards.
我知道<$中没有实际的暂停功能C $ C> Swing.Timer 。有没有办法解决这个问题,以便秒表恢复正常?
I am aware there isn't a actual pause function in Swing.Timer
. Would there be a way to tackle this so the stopwatch resumes normally?
任何建议都将受到赞赏。
Any suggestion would be appreciated.
代码:
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.time.Duration;
import java.time.Instant;
import javax.swing.Timer;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class GuiStopwatch {
public static void main(String[] args) {
JFrame frame = new JFrame("Stopwatch");
frame.setSize(500, 500);
frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
frame.setVisible(true);
JPanel panel = new JPanel();
panel.setLayout(null);
JButton startbtn = new JButton("START");
JButton pausebtn = new JButton("PAUSE");
JButton reset = new JButton("RESET");
JLabel time = new JLabel("Time shows here");
panel.add(startbtn);
panel.add(pausebtn);
panel.add(reset);
panel.add(time);
startbtn.setBounds(50, 150, 100, 35);
pausebtn.setBounds(50, 200, 100, 35);
reset.setBounds(50, 250, 100, 35);
time.setBounds(50, 350, 100, 35);
time.setBackground(Color.black);
time.setForeground(Color.red);
frame.add(panel);
Timer timer = new Timer(1,new ActionListener() {
Instant start = Instant.now();
@Override
public void actionPerformed(ActionEvent e) {
time.setText( Duration.between(start, Instant.now()).getSeconds() + ":" + Duration.between(start, Instant.now()).getNano() );
}
});
startbtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
timer.start();
}
});
pausebtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
timer.stop();
}
});
reset.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
time.setText("0:0");
}
});
推荐答案
从概念上讲,这个想法是,你要跟踪秒表的总运行,这是它一直处于活动状态的总持续时间。
Conceptually, the idea is, you want to keep track of the "total running" of the stop watch, this is, all the total duration it has been active.
有很多方法可以达到这个目的,一个可能只需保留一个仅在秒表停止或暂停时更新的运行总计。秒表的持续时间是当前周期的当前持续时间和总前一持续时间的总和
There's a number of ways you might achieve this, one might be to simply keep a running total which is only updated when the stop watch is stopped or paused. The "duration" of the stop watch is then a sum of the "current duration" of the "current" cycle and the "total previous" duration
类似于...... 。
Something like...
public class StopWatch {
private LocalDateTime startTime;
private Duration totalRunTime = Duration.ZERO;
public void start() {
startTime = LocalDateTime.now();
}
public void stop() {
Duration runTime = Duration.between(startTime, LocalDateTime.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, LocalDateTime.now());
currentDuration = currentDuration.plus(runTime);
}
return currentDuration;
}
}
好的,所以 start
和 stop
基本上与 pause
和 resume
,但你明白了。
Okay, so start
and stop
are essentially the same as pause
and resume
, but you get the point.
并且,一个可运行的例子......
And, a runnable example...
现在,此示例不断运行Swing Timer
,但 StopWatch
可以暂停
和在任何时候恢复
,重点是证明 StopWatch
实际上正常工作;)
Now, this example runs a Swing Timer
constantly, but the StopWatch
can paused
and resumed
at any time, the point is to demonstrate that the StopWatch
is actually working correctly ;)
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
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.LocalDateTime;
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 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) {
label.setText(Long.toString(stopWatch.getDuration().getSeconds()));
}
});
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);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.dispose();
}
}
public class StopWatch {
private LocalDateTime startTime;
private Duration totalRunTime = Duration.ZERO;
public void start() {
startTime = LocalDateTime.now();
}
public void stop() {
Duration runTime = Duration.between(startTime, LocalDateTime.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, LocalDateTime.now());
currentDuration = currentDuration.plus(runTime);
}
return currentDuration;
}
}
}
这篇关于将恢复功能添加到秒表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!