Adding resume function to stopwatch










-2














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.



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.



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.



Code:



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");


);









share|improve this question





















  • So, the "basic" concept is - you need to keep track the total ruining time of the stop watch, that is the time from when it was first started to when it was paused. When resumed, you would then add the "new running" time to the previous tally
    – MadProgrammer
    May 18 '18 at 10:02







  • 1




    panel.setLayout(null); <— avoid this.
    – achAmháin
    May 18 '18 at 10:03















-2














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.



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.



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.



Code:



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");


);









share|improve this question





















  • So, the "basic" concept is - you need to keep track the total ruining time of the stop watch, that is the time from when it was first started to when it was paused. When resumed, you would then add the "new running" time to the previous tally
    – MadProgrammer
    May 18 '18 at 10:02







  • 1




    panel.setLayout(null); <— avoid this.
    – achAmháin
    May 18 '18 at 10:03













-2












-2








-2







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.



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.



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.



Code:



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");


);









share|improve this question













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.



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.



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.



Code:



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");


);






java swing






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked May 18 '18 at 9:57









Lord Jesus

416




416











  • So, the "basic" concept is - you need to keep track the total ruining time of the stop watch, that is the time from when it was first started to when it was paused. When resumed, you would then add the "new running" time to the previous tally
    – MadProgrammer
    May 18 '18 at 10:02







  • 1




    panel.setLayout(null); <— avoid this.
    – achAmháin
    May 18 '18 at 10:03
















  • So, the "basic" concept is - you need to keep track the total ruining time of the stop watch, that is the time from when it was first started to when it was paused. When resumed, you would then add the "new running" time to the previous tally
    – MadProgrammer
    May 18 '18 at 10:02







  • 1




    panel.setLayout(null); <— avoid this.
    – achAmháin
    May 18 '18 at 10:03















So, the "basic" concept is - you need to keep track the total ruining time of the stop watch, that is the time from when it was first started to when it was paused. When resumed, you would then add the "new running" time to the previous tally
– MadProgrammer
May 18 '18 at 10:02





So, the "basic" concept is - you need to keep track the total ruining time of the stop watch, that is the time from when it was first started to when it was paused. When resumed, you would then add the "new running" time to the previous tally
– MadProgrammer
May 18 '18 at 10:02





1




1




panel.setLayout(null); <— avoid this.
– achAmháin
May 18 '18 at 10:03




panel.setLayout(null); <— avoid this.
– achAmháin
May 18 '18 at 10:03












1 Answer
1






active

oldest

votes


















3














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;




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



And, a runnable example...



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() InstantiationException
);


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;









share|improve this answer






















  • So , Instant.now() is not ideal in my situation rather compared to using LocalDateTime.now() ?
    – Lord Jesus
    May 18 '18 at 10:22










  • @LordJesus To be honest, I just know how to deal with LocalDateTime :P
    – MadProgrammer
    May 18 '18 at 10:29










  • @LordJesus Did a quick check, replaced LocalDateTime with Instant and seems to work just fine
    – MadProgrammer
    May 18 '18 at 10:34










  • I see. Your solution is fine but it's far more code written than mine. I guess to keep track of the "running" time, this is probably the best way to go?
    – Lord Jesus
    May 18 '18 at 10:51










  • I'm also comparing your solution to mine. I guess the difference is you added more logical code to keep track of the time and then upon clicking resume, you add it back to the previous tally. Am i correct?
    – Lord Jesus
    May 18 '18 at 10:53










Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f50408678%2fadding-resume-function-to-stopwatch%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









3














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;




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



And, a runnable example...



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() InstantiationException
);


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;









share|improve this answer






















  • So , Instant.now() is not ideal in my situation rather compared to using LocalDateTime.now() ?
    – Lord Jesus
    May 18 '18 at 10:22










  • @LordJesus To be honest, I just know how to deal with LocalDateTime :P
    – MadProgrammer
    May 18 '18 at 10:29










  • @LordJesus Did a quick check, replaced LocalDateTime with Instant and seems to work just fine
    – MadProgrammer
    May 18 '18 at 10:34










  • I see. Your solution is fine but it's far more code written than mine. I guess to keep track of the "running" time, this is probably the best way to go?
    – Lord Jesus
    May 18 '18 at 10:51










  • I'm also comparing your solution to mine. I guess the difference is you added more logical code to keep track of the time and then upon clicking resume, you add it back to the previous tally. Am i correct?
    – Lord Jesus
    May 18 '18 at 10:53















3














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;




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



And, a runnable example...



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() InstantiationException
);


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;









share|improve this answer






















  • So , Instant.now() is not ideal in my situation rather compared to using LocalDateTime.now() ?
    – Lord Jesus
    May 18 '18 at 10:22










  • @LordJesus To be honest, I just know how to deal with LocalDateTime :P
    – MadProgrammer
    May 18 '18 at 10:29










  • @LordJesus Did a quick check, replaced LocalDateTime with Instant and seems to work just fine
    – MadProgrammer
    May 18 '18 at 10:34










  • I see. Your solution is fine but it's far more code written than mine. I guess to keep track of the "running" time, this is probably the best way to go?
    – Lord Jesus
    May 18 '18 at 10:51










  • I'm also comparing your solution to mine. I guess the difference is you added more logical code to keep track of the time and then upon clicking resume, you add it back to the previous tally. Am i correct?
    – Lord Jesus
    May 18 '18 at 10:53













3












3








3






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;




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



And, a runnable example...



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() InstantiationException
);


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;









share|improve this answer














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;




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



And, a runnable example...



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() InstantiationException
);


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;










share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 11 '18 at 22:07

























answered May 18 '18 at 10:16









MadProgrammer

298k17153265




298k17153265











  • So , Instant.now() is not ideal in my situation rather compared to using LocalDateTime.now() ?
    – Lord Jesus
    May 18 '18 at 10:22










  • @LordJesus To be honest, I just know how to deal with LocalDateTime :P
    – MadProgrammer
    May 18 '18 at 10:29










  • @LordJesus Did a quick check, replaced LocalDateTime with Instant and seems to work just fine
    – MadProgrammer
    May 18 '18 at 10:34










  • I see. Your solution is fine but it's far more code written than mine. I guess to keep track of the "running" time, this is probably the best way to go?
    – Lord Jesus
    May 18 '18 at 10:51










  • I'm also comparing your solution to mine. I guess the difference is you added more logical code to keep track of the time and then upon clicking resume, you add it back to the previous tally. Am i correct?
    – Lord Jesus
    May 18 '18 at 10:53
















  • So , Instant.now() is not ideal in my situation rather compared to using LocalDateTime.now() ?
    – Lord Jesus
    May 18 '18 at 10:22










  • @LordJesus To be honest, I just know how to deal with LocalDateTime :P
    – MadProgrammer
    May 18 '18 at 10:29










  • @LordJesus Did a quick check, replaced LocalDateTime with Instant and seems to work just fine
    – MadProgrammer
    May 18 '18 at 10:34










  • I see. Your solution is fine but it's far more code written than mine. I guess to keep track of the "running" time, this is probably the best way to go?
    – Lord Jesus
    May 18 '18 at 10:51










  • I'm also comparing your solution to mine. I guess the difference is you added more logical code to keep track of the time and then upon clicking resume, you add it back to the previous tally. Am i correct?
    – Lord Jesus
    May 18 '18 at 10:53















So , Instant.now() is not ideal in my situation rather compared to using LocalDateTime.now() ?
– Lord Jesus
May 18 '18 at 10:22




So , Instant.now() is not ideal in my situation rather compared to using LocalDateTime.now() ?
– Lord Jesus
May 18 '18 at 10:22












@LordJesus To be honest, I just know how to deal with LocalDateTime :P
– MadProgrammer
May 18 '18 at 10:29




@LordJesus To be honest, I just know how to deal with LocalDateTime :P
– MadProgrammer
May 18 '18 at 10:29












@LordJesus Did a quick check, replaced LocalDateTime with Instant and seems to work just fine
– MadProgrammer
May 18 '18 at 10:34




@LordJesus Did a quick check, replaced LocalDateTime with Instant and seems to work just fine
– MadProgrammer
May 18 '18 at 10:34












I see. Your solution is fine but it's far more code written than mine. I guess to keep track of the "running" time, this is probably the best way to go?
– Lord Jesus
May 18 '18 at 10:51




I see. Your solution is fine but it's far more code written than mine. I guess to keep track of the "running" time, this is probably the best way to go?
– Lord Jesus
May 18 '18 at 10:51












I'm also comparing your solution to mine. I guess the difference is you added more logical code to keep track of the time and then upon clicking resume, you add it back to the previous tally. Am i correct?
– Lord Jesus
May 18 '18 at 10:53




I'm also comparing your solution to mine. I guess the difference is you added more logical code to keep track of the time and then upon clicking resume, you add it back to the previous tally. Am i correct?
– Lord Jesus
May 18 '18 at 10:53

















draft saved

draft discarded
















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f50408678%2fadding-resume-function-to-stopwatch%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

How to how show current date and time by default on contact form 7 in WordPress without taking input from user in datetimepicker

Syphilis

Darth Vader #20