将恢复功能添加到秒表 [英] Adding resume function to stopwatch

查看:85
本文介绍了将恢复功能添加到秒表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我编写了一个带有三种功能的简单秒表。首先,我有一个开始秒表的开始按钮,一个用于暂停秒表的暂停按钮,以及一个用于重置整个秒表的重置按钮。

I have programmed a simple stopwatch with three functionalities. First, I have a start button to begin the stopwatch , a pause button to pause the stopwatch and finally a reset button to reset the entire stopwatch.

当我点击暂停按钮时,秒表暂停,比如说10.0秒。当我恢复秒表(再次按下开始按钮)时,秒表不会从10.0秒开始恢复。它从我暂停的时间和当前时间恢复。例如,如果我暂停5秒钟并且恢复恢复,秒表将从15.0秒开始。

When I hit the pause button, the stopwatch pauses, say at 10.0 seconds. When I resume the stopwatch (pressing the Start button again), the stopwatch doesn't resume from 10.0 seconds onwards. It resumes from the amount of time I paused and the current time. For example, if I paused for 5 seconds and hit resume, the stopwatch goes from 15.0 seconds onwards.

我知道<$中没有实际的暂停功能C $ C> Swing.Timer 。有没有办法解决这个问题,以便秒表恢复正常?

I am aware there isn't a actual pause function in Swing.Timer. Would there be a way to tackle this so the stopwatch resumes normally?

任何建议都将受到赞赏。

Any suggestion would be appreciated.

代码:

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.time.Duration;
import java.time.Instant;
import javax.swing.Timer;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;



public class GuiStopwatch {





    public static void main(String[] args) {
        JFrame frame = new JFrame("Stopwatch");

        frame.setSize(500, 500);
        frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
        frame.setVisible(true);
          JPanel panel = new JPanel();

          panel.setLayout(null);

          JButton startbtn = new JButton("START");  
          JButton pausebtn = new JButton("PAUSE");
          JButton reset = new JButton("RESET");
          JLabel time = new JLabel("Time shows here");
             panel.add(startbtn);
             panel.add(pausebtn);
            panel.add(reset);
            panel.add(time);
             startbtn.setBounds(50, 150, 100, 35);
             pausebtn.setBounds(50, 200, 100, 35);
             reset.setBounds(50, 250, 100, 35);
             time.setBounds(50, 350, 100, 35);
             time.setBackground(Color.black);
             time.setForeground(Color.red);
             frame.add(panel);



            Timer timer = new Timer(1,new ActionListener() {
                Instant start = Instant.now();
                @Override
                public void actionPerformed(ActionEvent e) {


                    time.setText( Duration.between(start, Instant.now()).getSeconds() +  ":" + Duration.between(start, Instant.now()).getNano() );


                }
            });



             startbtn.addActionListener(new ActionListener() {


                @Override
                public void actionPerformed(ActionEvent e) {





                timer.start();




                }
            });



             pausebtn.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {

                    timer.stop();

                }
            });



             reset.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                time.setText("0:0");

                }
            });


推荐答案

从概念上讲,这个想法是,你要跟踪秒表的总运行,这是它一直处于活动状态的总持续时间。

Conceptually, the idea is, you want to keep track of the "total running" of the stop watch, this is, all the total duration it has been active.

有很多方法可以达到这个目的,一个可能只需保留一个仅在秒表停止或暂停时更新的运行总计。秒表的持续时间是当前周期的当前持续时间和总前一持续时间的总和

There's a number of ways you might achieve this, one might be to simply keep a running total which is only updated when the stop watch is stopped or paused. The "duration" of the stop watch is then a sum of the "current duration" of the "current" cycle and the "total previous" duration

类似于...... 。

Something like...

public class StopWatch {
    private LocalDateTime startTime;
    private Duration totalRunTime = Duration.ZERO;

    public void start() {
        startTime = LocalDateTime.now();
    }

    public void stop() {
        Duration runTime = Duration.between(startTime, LocalDateTime.now());
        totalRunTime = totalRunTime.plus(runTime);
        startTime = null;
    }

    public void pause() {
        stop();
    }

    public void resume() {
        start();
    }

    public void reset() {
        stop();
        totalRunTime = Duration.ZERO;
    }

    public boolean isRunning() {
        return startTime != null;
    }

    public Duration getDuration() {
        Duration currentDuration = Duration.ZERO;
        currentDuration = currentDuration.plus(totalRunTime);
        if (isRunning()) {
            Duration runTime = Duration.between(startTime, LocalDateTime.now());
            currentDuration = currentDuration.plus(runTime);
        }
        return currentDuration;
    }
}

好的,所以 start stop 基本上与 pause resume ,但你明白了。

Okay, so start and stop are essentially the same as pause and resume, but you get the point.

并且,一个可运行的例子......

And, a runnable example...

现在,此示例不断运行Swing Timer ,但 StopWatch 可以暂停在任何时候恢复,重点是证明 StopWatch 实际上正常工作;)

Now, this example runs a Swing Timer constantly, but the StopWatch can paused and resumed at any time, the point is to demonstrate that the StopWatch is actually working correctly ;)

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.time.Duration;
import java.time.LocalDateTime;
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) throws InterruptedException {
        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 JButton btn;

        private StopWatch stopWatch = new StopWatch();
        private Timer timer;

        public TestPane() {
            label = new JLabel("...");
            btn = new JButton("Start");

            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridwidth = GridBagConstraints.REMAINDER;

            add(label, gbc);
            add(btn, gbc);

            timer = new Timer(500, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    label.setText(Long.toString(stopWatch.getDuration().getSeconds()));
                }
            });
            timer.start();

            btn.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (stopWatch.isRunning()) {
                        stopWatch.pause();
                        btn.setText("Start");
                    } else {
                        stopWatch.resume();
                        btn.setText("Pause");
                    }
                }
            });

        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.dispose();
        }

    }

    public class StopWatch {
        private LocalDateTime startTime;
        private Duration totalRunTime = Duration.ZERO;

        public void start() {
            startTime = LocalDateTime.now();
        }

        public void stop() {
            Duration runTime = Duration.between(startTime, LocalDateTime.now());
            totalRunTime = totalRunTime.plus(runTime);
            startTime = null;
        }

        public void pause() {
            stop();
        }

        public void resume() {
            start();
        }

        public void reset() {
            stop();
            totalRunTime = Duration.ZERO;
        }

        public boolean isRunning() {
            return startTime != null;
        }

        public Duration getDuration() {
            Duration currentDuration = Duration.ZERO;
            currentDuration = currentDuration.plus(totalRunTime);
            if (isRunning()) {
                Duration runTime = Duration.between(startTime, LocalDateTime.now());
                currentDuration = currentDuration.plus(runTime);
            }
            return currentDuration;
        }
    }

}

这篇关于将恢复功能添加到秒表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆