用Java创建Stop Watch的Timer Delay方法

时间:2015-08-01 08:40:35

标签: java timer

您好我正在尝试为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秒,数字加起来太慢了。

我做错了什么?

2 个答案:

答案 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()。