Adding resume function to stopwatch
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
add a comment |
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
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
add a comment |
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
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
java swing
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
add a comment |
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
add a comment |
1 Answer
1
active
oldest
votes
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;
So ,Instant.now()
is not ideal in my situation rather compared to usingLocalDateTime.now()
?
– Lord Jesus
May 18 '18 at 10:22
@LordJesus To be honest, I just know how to deal withLocalDateTime
:P
– MadProgrammer
May 18 '18 at 10:29
@LordJesus Did a quick check, replacedLocalDateTime
withInstant
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
|
show 5 more comments
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
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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;
So ,Instant.now()
is not ideal in my situation rather compared to usingLocalDateTime.now()
?
– Lord Jesus
May 18 '18 at 10:22
@LordJesus To be honest, I just know how to deal withLocalDateTime
:P
– MadProgrammer
May 18 '18 at 10:29
@LordJesus Did a quick check, replacedLocalDateTime
withInstant
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
|
show 5 more comments
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;
So ,Instant.now()
is not ideal in my situation rather compared to usingLocalDateTime.now()
?
– Lord Jesus
May 18 '18 at 10:22
@LordJesus To be honest, I just know how to deal withLocalDateTime
:P
– MadProgrammer
May 18 '18 at 10:29
@LordJesus Did a quick check, replacedLocalDateTime
withInstant
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
|
show 5 more comments
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;
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;
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 usingLocalDateTime.now()
?
– Lord Jesus
May 18 '18 at 10:22
@LordJesus To be honest, I just know how to deal withLocalDateTime
:P
– MadProgrammer
May 18 '18 at 10:29
@LordJesus Did a quick check, replacedLocalDateTime
withInstant
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
|
show 5 more comments
So ,Instant.now()
is not ideal in my situation rather compared to usingLocalDateTime.now()
?
– Lord Jesus
May 18 '18 at 10:22
@LordJesus To be honest, I just know how to deal withLocalDateTime
:P
– MadProgrammer
May 18 '18 at 10:29
@LordJesus Did a quick check, replacedLocalDateTime
withInstant
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
|
show 5 more comments
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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