您好我正在尝试为Java Foundations Textbook中的一个项目问题创建一个StopWatch应用程序。到目前为止,我已经编写了这段代码:
package StopWatch;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class StopWatchPanel extends JPanel{
private JPanel userPanel = new JPanel();
private JLabel timeDisplay = new JLabel("00:00:00", SwingConstants.CENTER);
private JButton startButton = new JButton("Start");
private JButton stopButton = new JButton("Stop");
private JButton resetButton = new JButton("Reset");
private Timer refreshRate = new Timer(1, new ActionListen());
private int milliseconds, seconds, minutes, hours;
public StopWatchPanel(){
// user panel settings
userPanel.setPreferredSize(new Dimension(400, 100));
userPanel.setBackground(new Color(200, 200, 255));
// add listeners
startButton.addActionListener(new ActionListen());
stopButton.addActionListener(new ActionListen());
resetButton.addActionListener(new ActionListen());
// component setting
timeDisplay.setPreferredSize(new Dimension(400, 50));
// add components
userPanel.add(timeDisplay);
userPanel.add(startButton);
userPanel.add(stopButton);
userPanel.add(resetButton);
// add to main frame
add(userPanel);
}
private int milsec(){
if(milliseconds > 1000){
milliseconds = 0;
seconds++;
}
return milliseconds++;
}
private int sec(){
if(seconds > 59){
seconds = 0;
minutes++;
}
return seconds;
}
private int min(){
if(minutes > 59){
minutes = 0;
hours++;
}
return minutes;
}
private int hrs(){
if(hours > 23){
hours = 0;
}
return hours;
}
private class ActionListen implements ActionListener{
public void actionPerformed(ActionEvent e){
if(e.getSource().equals(startButton)){
refreshRate.start();
}
else if(e.getSource().equals(refreshRate)){
timeDisplay.setText(sec()+":"+milsec());
}
else if(e.getSource().equals(stopButton)){
refreshRate.stop();
}
else if(e.getSource().equals(resetButton)){
timeDisplay.setText("00:00:00");
milliseconds = 0;
seconds = 0;
minutes = 0;
hours = 0;
}
}
}
}
如果我将定时器的延迟设置为1000ms,因此显示秒数(如果我排除了milsec方法),但我想显示毫秒数。所以我把延迟放到1ms,这样在每1ms之后,它会将setText设置为当前的秒数(秒方法)。 但由于某种原因,这不起作用,因为考虑到1000毫秒= 1秒,数字加起来太慢了。
我做错了什么?
答案 0 :(得分:0)
1 ms的延迟意味着定时器每1毫秒产生一次事件。然后将事件调度到事件调度线程,这引入了延迟(因为还有其他代码也在事件调度线程上运行),因此对actionPerformed()的调用之间的实际间隔可能大于1毫秒。
如果您需要时钟精确,则需要测量呼叫之间的确切时间(例如,使用System.currentTimeMillis()
方法),而不是每次呼叫时将时间增加1 ms。 / p>
答案 1 :(得分:0)
您可以通过改变毫秒间隔来提高输出的及时性。而不是1毫秒,你可以尝试间隔10秒,20秒或50毫秒。下面的代码使用100毫秒。
package StopWatch;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class StopWatchPanel extends JPanel {
private JPanel userPanel = new JPanel();
private JLabel timeDisplay = new JLabel("00:00:00", SwingConstants.CENTER);
private JButton startButton = new JButton("Start");
private JButton stopButton = new JButton("Stop");
private JButton resetButton = new JButton("Reset");
private Timer refreshRate = new Timer(100, new ActionListen());
private int milliseconds, seconds, minutes, hours;
public StopWatchPanel(){
// user panel settings
userPanel.setPreferredSize(new Dimension(400, 100));
userPanel.setBackground(new Color(200, 200, 255));
// add listeners
startButton.addActionListener(new ActionListen());
stopButton.addActionListener(new ActionListen());
resetButton.addActionListener(new ActionListen());
// component setting
timeDisplay.setPreferredSize(new Dimension(400, 50));
// add components
userPanel.add(timeDisplay);
userPanel.add(startButton);
userPanel.add(stopButton);
userPanel.add(resetButton);
// add to main frame
add(userPanel);
}
private int milsec(){
milliseconds+=100;
if(milliseconds >= 1000){
milliseconds = 0;
seconds++;
}
return milliseconds;
}
private int sec(){
if(seconds > 59){
seconds = 0;
minutes++;
}
return seconds;
}
private int min(){
if(minutes > 59){
minutes = 0;
hours++;
}
return minutes;
}
private int hrs(){
if(hours > 23){
hours = 0;
}
return hours;
}
private class ActionListen implements ActionListener{
public void actionPerformed(ActionEvent e){
if(e.getSource().equals(startButton)){
refreshRate.start();
}
else if(e.getSource().equals(refreshRate)){
int tms = milsec();
int tsec = sec();
int tmin = min();
int thr = hrs();
timeDisplay.setText(thr + ":" +tmin+ ":" +tsec+ "." +tms/100);
}
else if(e.getSource().equals(stopButton)){
refreshRate.stop();
}
else if(e.getSource().equals(resetButton)){
timeDisplay.setText("00:00:00");
milliseconds = 0;
seconds = 0;
minutes = 0;
hours = 0;
}
}
}
}
我认为原始代码主要用于演示目的,并不太关注时间的准确性。如果您想要更实时的输出,则需要尝试不同的方法。在这种情况下,您可以使用另一个答案所指出的System.currentTimeMillis()。