【发布时间】:2014-01-09 04:59:47
【问题描述】:
我花了一些时间来开发一个程序,该程序显示用户单击开始按钮后经过的时间或剩余时间,就像秒表或计时器一样,它会测量时间,直到您停止并重置。衡量经过时间的其他示例包括赛车游戏中的单圈时间和其他游戏中的时间限制(以毫秒为单位)。
不过,我遇到了一些麻烦,因为我自己的秒表运行速度与实际时间不同。我的计时器向下或向上运行一秒需要超过一秒的时间。
代码就在这里:(GUI 完美运行;我更关心如何控制值以显示经过的时间,每经过一秒,JLabel 上显示的时间就是一个秒少。我无法修改传递给 Thread.sleep 的参数,因为它会使计时器变得更糟。)
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.text.DecimalFormat;
import java.util.concurrent.*;
public class StopwatchGUI3 extends JFrame
{
private static final long serialVersionUID = 3545053785228009472L;
// GUI Components
private JPanel panel;
private JLabel timeLabel;
private JPanel buttonPanel;
private JButton startButton;
private JButton resetButton;
private JButton stopButton;
// Properties of Program.
private byte centiseconds = 0;
private byte seconds = 30;
private short minutes = 0;
private Runnable timeTask;
private Runnable incrementTimeTask;
private Runnable setTimeTask;
private DecimalFormat timeFormatter;
private boolean timerIsRunning = true;
private ExecutorService executor = Executors.newCachedThreadPool();
public StopwatchGUI3()
{
panel = new JPanel();
panel.setLayout(new BorderLayout());
timeLabel = new JLabel();
timeLabel.setFont(new Font("Consolas", Font.PLAIN, 13));
timeLabel.setHorizontalAlignment(JLabel.CENTER);
panel.add(timeLabel);
buttonPanel = new JPanel();
buttonPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
startButton = new JButton("Start");
startButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
if (!timerIsRunning)
timerIsRunning = true;
executor.execute(timeTask);
}
});
buttonPanel.add(startButton);
resetButton = new JButton("Reset");
resetButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
timerIsRunning = false;
centiseconds = 0;
seconds = 30;
minutes = 0;
timeLabel.setText(timeFormatter.format(minutes) + ":"
+ timeFormatter.format(seconds) + "."
+ timeFormatter.format(centiseconds));
}
});
buttonPanel.add(resetButton);
stopButton = new JButton("Stop");
stopButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
timerIsRunning = false;
}
});
buttonPanel.add(stopButton);
panel.add(buttonPanel, BorderLayout.SOUTH);
timeFormatter = new DecimalFormat("00");
timeTask = new Runnable(){
public void run()
{
while(timerIsRunning)
{
executor.execute(incrementTimeTask);
try
{
Thread.sleep(10);
}
catch (InterruptedException ex)
{
ex.printStackTrace();
}
}
}
};
incrementTimeTask = new Runnable(){
public void run()
{
if (centiseconds > 0)
centiseconds--;
else
{
if (seconds == 0 && minutes == 0)
timerIsRunning = false;
else if (seconds > 0)
{
seconds--;
centiseconds = 99;
}
else if (minutes > 0)
{
minutes--;
seconds = 59;
centiseconds = 99;
}
}
executor.execute(setTimeTask);
}
};
setTimeTask = new Runnable(){
public void run()
{
timeLabel.setText(timeFormatter.format(minutes) + ":"
+ timeFormatter.format(seconds) + "."
+ timeFormatter.format(centiseconds));
}
};
timeLabel.setText(timeFormatter.format(minutes) + ":"
+ timeFormatter.format(seconds) + "."
+ timeFormatter.format(centiseconds));
add(panel);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setTitle("StopwatchGUI.java");
pack();
setVisible(true);
}
public static void main(String[] args)
{
new StopwatchGUI3();
}
}
必须有另一种方法使计时器与实时同步,就像真正的秒表一样,而不是必须依赖三个单独的线程,我认为对于这样一个大型编程项目来说太多了,但还可以目前入门级。 (哦,顺便说一下,DecimalFormat 类是像真正的秒表一样正确格式化数字,尽管没有十进制值要四舍五入。直到现在,在我发布这个时,存在一个文本类叫SimpleDateFormat。)
换句话说,我希望这个程序只是一个真正的秒表。如果不是这种情况,那么如何在 Java 游戏中创建或使用秒表?
【问题讨论】:
-
尝试使用 Swing
Timer代替
标签: java swing timer stopwatch chronometer