我在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);
}
}
计时器工作正常,这肯定远未完成,但我不知道如何编码应该停止计时器的停止按钮。有什么建议吗?顺便说一下,我正在使用java.util.timer
编辑:我希望能够在停止后再次启动它(没有重置计时器)
答案 0 :(得分:5)
您可以通过拨打Timer
取消整个Timer.cancel()
,也可以致电TimerTask.cancel()
取消各个任务。
无论哪种方式,您都需要在创建时保留对计时器和/或任务实例的引用,以便您的停止例程可以调用相应的cancel方法。
更新
所以你有效地希望能够暂停计时器吗?我不认为java.util.Timer
中的标准接口支持这一点。您可以通过向自定义任务添加pause()
方法(或类似方法),记录截至该点的已用时间,并在再次单击开始按钮时重新开始计数。请注意,使用此技术,在完成完成之前,您不会停止计时器任务。它仍然在后台运行,但是当秒表启动并且“正在运行”时(即某种标志指示秒表的状态),你只对它做任何事情。
几点说明:
java.util.Timer
在非EDT线程上运行,因此如果您在计时器和Swing操作事件中与成员变量进行交互,则需要适当地处理多线程的含义。可能值得调查javax.swing.Timer
,这将在美国东部时间发生事件。
此外,如果你想要一个超级精确的秒表,你可以考虑使用System.nanoTime()
而不是currentTimeMillis()
。
答案 1 :(得分:5)
如果javax.swing.Timer
是可接受的替代方案,正如@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();
}
});
}
}
答案 2 :(得分:3)
我改变了trashgod的来源。
更新
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();
}
});
}
}
答案 3 :(得分:1)
long startTime = System.currentTimeMillis();
Timer timer = new Timer(100,new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
long elapsedTime = System.currentTimeMillis()-startTime;
long mil = elapsedTime%1000;
long sec = elapsedTime/1000%60;
long min = elapsedTime/60000%60;
long hr = elapsedTime/3600000;
label.setText(String.format("%02d:%02d:%02d.%03d", hr,min,sec,mil));
}
});
timer.start();