我花了一些时间来开发一个程序,显示经过的时间或剩余时间,从用户单击开始按钮开始,就像秒表或计时器一样,它测量时间,直到您停止和重置。测量经过时间的其他示例是赛车游戏中的单圈时间和其他游戏中的时间限制(以毫秒为单位)。
不过,我遇到了一些麻烦,因为我自己的秒表运行速度与实际时间不同。我的计时器向下或向上运行一秒钟需要超过一秒钟的时间。
代码就在这里:(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 游戏中创建或使用秒表?