停止一个秒表

我有一个JPanel类中添加到另一个类(JFrame)的以下代码。 我想要实现的是某种秒表程序。

startBtn.addActionListener(new startListener()); class startListener implements ActionListener { public void actionPerformed(ActionEvent e) { Timer time = new Timer(); time.scheduleAtFixedRate(new Stopwatch(), 1000, 1000); } } 

这是另外一个基本上任务的课。

 public class Stopwatch extends TimerTask { private final double start = System.currentTimeMillis(); public void run() { double curr = System.currentTimeMillis(); System.out.println((curr - start) / 1000); } } 

计时器工作正常,这是肯定远远没有完成,但我不知道如何编码应该停止计时器的停止button。 对此有何build议? 顺便说一句我正在使用java.util.timer

编辑:我想能够在停止它之后再次启动它(没有定时器被重置)

您可以通过调用Timer.cancel()来取消整个Timer ,也可以通过调用TimerTask.cancel()来取消单个任务。

无论哪种方式,创build时都需要保留对定时器和/或任务实例的引用,以便停止例程可以调用相应的取消方法。

更新:

所以你有效的想要暂停计时器? 我不认为这是由java.util.Timer的标准接口支持。 您可以通过向您的自定义任务添加一个pause()方法(或类似方法),logging到达该点的经过时间,并在再次单击开始button时重新开始计算。 请注意,使用这种技术,您不会完全停止计时器任务本身。 它仍然在后台运行,但是当秒表已经启动并且正在“运行”时(即某种标志来指示秒表的状态),你只能做任何事情。

几个注意事项:

  • java.util.Timer在非EDT线程上运行,所以如果您在定时器和Swing动作事件中与成员variables进行交互,则需要适当地处理多个线程的影响。 可能值得研究javax.swing.Timer ,它将触发EDT上的事件。

  • 另外,如果你想要一个超级准确的秒表,你可以考虑使用System.nanoTime()而不是currentTimeMillis()

如果javax.swing.Timer是一个可以接受的select,就像@Ash所示,这里是一个例子。

 import java.awt.BorderLayout; import java.awt.EventQueue; import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.text.DecimalFormat; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.Timer; /** @see http://stackoverflow.com/questions/2576909 */ public class JTimeLabel extends JLabel implements ActionListener { private static final String Start = "Start"; private static final String Stop = "Stop"; private DecimalFormat df = new DecimalFormat("000.0"); private Timer timer = new javax.swing.Timer(100, this); private long now = System.currentTimeMillis(); public JTimeLabel() { this.setHorizontalAlignment(JLabel.CENTER); this.setText(when()); } public void actionPerformed(ActionEvent ae) { setText(when()); } public void start() { timer.start(); } public void stop() { timer.stop(); } private String when() { return df.format((System.currentTimeMillis() - now) / 1000d); } private static void create() { JFrame f = new JFrame(); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); final JTimeLabel jtl = new JTimeLabel(); jtl.setFont(new Font("Dialog", Font.BOLD, 32)); f.add(jtl, BorderLayout.CENTER); final JButton button = new JButton(Stop); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { String cmd = e.getActionCommand(); if (Stop.equals(cmd)) { jtl.stop(); button.setText(Start); } else { jtl.start(); button.setText(Stop); } } }); f.add(button, BorderLayout.SOUTH); f.pack(); f.setVisible(true); jtl.start(); } public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { create(); } }); } } 

这里是我的来源。 我改变了垃圾的来源。

更新

  • 暂停function
  • 重置function

 public class StopWatch extends JLabel implements ActionListener { private static final String Start = "Start"; private static final String Pause = "Pause"; private static final String Reset = "Reset"; private boolean isRunning; private Timer timer = new javax.swing.Timer(100, this); private long initTime = System.currentTimeMillis(); private long startTime; private long pauseTime; public StopWatch() { this.setHorizontalAlignment(JLabel.CENTER); this.setText(getCurrentTime(System.currentTimeMillis() - initTime)); } public void actionPerformed(ActionEvent ae) { setText(getCurrentTime(System.currentTimeMillis() - startTime)); } public void start() { if (isRunning == false) { startTime = System.currentTimeMillis(); } else { startTime = System.currentTimeMillis() - (pauseTime - startTime); } isRunning = true; timer.start(); } public void pause() { pauseTime = System.currentTimeMillis(); timer.stop(); } public void reset() { startTime = 0; isRunning = false; this.setText(getCurrentTime(System.currentTimeMillis() - System.currentTimeMillis())); } private String getCurrentTime(long time) { return myFormat(time); } private String myFormat(final long time) { final long hr = TimeUnit.MILLISECONDS.toHours(time); final long min = TimeUnit.MILLISECONDS.toMinutes(time - TimeUnit.HOURS.toMillis(hr)); final long sec = TimeUnit.MILLISECONDS.toSeconds(time - TimeUnit.HOURS.toMillis(hr) - TimeUnit.MINUTES.toMillis(min)); final long ms = TimeUnit.MILLISECONDS.toMillis(time - TimeUnit.HOURS.toMillis(hr) - TimeUnit.MINUTES.toMillis(min) - TimeUnit.SECONDS.toMillis(sec)); return String.format("%02d:%02d:%02d.%01d", hr, min, sec, ms/100); } private static void create() { JFrame f = new JFrame(); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); final StopWatch textLabel = new StopWatch(); textLabel.setFont(new Font("Dialog", Font.BOLD, 32)); f.add(textLabel, BorderLayout.CENTER); final JButton button = new JButton(Start); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { String cmd = e.getActionCommand(); if (Pause.equals(cmd)) { textLabel.pause(); button.setText(Start); } else { textLabel.start(); button.setText(Pause); } } }); final JButton button2 = new JButton(Reset); button2.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { textLabel.reset(); } }); f.add(button, BorderLayout.SOUTH); f.add(button2, BorderLayout.NORTH); f.pack(); f.setVisible(true); } public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { create(); } }); } }