你需要以某种方式暂停Thread
并停止更新的发生。你可以用if
你里面的声明run
循环,但是有一种更有效的方法,通过使用监视器锁
public class Stopwatch extends Thread {
//...
private final Object pauseLock;
public Stopwatch() {
pauseLock = new Object();
}
public Stopwatch(boolean finished, boolean pause, boolean sort, JLabel timer) {
this();
//...
}
@Override
public void run() {
long startTime = System.currentTimeMillis();
while (sortFlag && !finishedFlag) {
while (pauseFlag) {
synchronized (pauseLock) {
try {
pauseLock.wait();
} catch (InterruptedException ex) {
}
}
}
update(summedTime + (System.currentTimeMillis() - startTime));
}
if (pauseFlag) {
summedTime += System.currentTimeMillis() - startTime;
} else {
summedTime = 0;
}
}
现在,您需要某种方法来暂停和恢复run
loop
public void setPaused(boolean paused) {
if (paused && !pauseFlag) {
pauseFlag = paused;
} else if (!paused && pauseFlag) {
pauseFlag = paused;
synchronized (pauseLock) {
pauseLock.notifyAll();
}
}
}
然而,现在我们有更大的问题,Swing 不是线程安全的。这意味着您的update
方法违反了 Swing 的单线程规则,可能会导致无穷无尽的问题......
一个更简单的解决方案是只使用 SwingTimer
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
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) {
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 StopWatch sw;
public TestPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
label = new JLabel("...");
add(label, gbc);
sw = new StopWatch(label);
JButton btn = new JButton("Resume");
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
sw.setPaused(!sw.isPaused());
btn.setText(sw.isPaused() ? "Resume" : "Pause");
}
});
add(btn, gbc);
}
}
public class StopWatch {
private Timer timer;
private JLabel label;
private int runningTime;
private long tickTime;
public StopWatch(JLabel label) {
this.label = label;
timer = new Timer(10, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
runningTime += (System.currentTimeMillis() - tickTime);
System.out.println(runningTime);
update(runningTime);
tickTime = System.currentTimeMillis();
}
});
}
public void setPaused(boolean paused) {
if (paused && timer.isRunning()) {
timer.stop();
} else if (!paused && !timer.isRunning()) {
tickTime = System.currentTimeMillis();
timer.start();
}
}
public boolean isPaused() {
return !timer.isRunning();
}
private void update(long dT) {
long x = (dT / 1000) % 60;
long y = (dT / 60000) % 1000;
if (x >= 0 && x <= 9 && y >= 0 && y <= 9) {
label.setText("0" + String.valueOf((dT / 60000) % 1000) + ":0" + String.valueOf((dT / 1000) % 60) + "," + String.valueOf((dT) % 1000));
} else if (x > 9 && y >= 0 && y <= 9) {
label.setText("0" + String.valueOf((dT / 60000) % 1000) + ":" + String.valueOf((dT / 1000) % 60) + "," + String.valueOf((dT) % 1000));
} else if (x >= 0 && x <= 9 && y > 9) {
label.setText(String.valueOf((dT / 60000) % 1000) + ":0" + String.valueOf((dT / 1000) % 60) + "," + String.valueOf((dT) % 1000));
} else if (x > 9 && y > 9) {
label.setText(String.valueOf((dT / 60000) % 1000) + ":" + String.valueOf((dT / 1000) % 60) + "," + String.valueOf((dT) % 1000));
}
}
}
}
See 如何使用 Swing 定时器 http://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html更多细节