How do I add pause and resume methods to this class?
When you pause and it is already paused then nothing should happen.
Also if you resume when it is not paused nothing should happen.
public class Stopwatch {
private final long start;
public Stopwatch() {
start = System.currentTimeMillis();}
public double elapsedTime() {
long now = System.currentTimeMillis();
return (now - start) / 1000.0;}
public static void main(String[] args) {
Stopwatch watch = new Stopwatch();
double total = 0.0;
for (int i = 0; i < 100000000; i++)
total += Math.random();
double time = watch.elapsedTime();
StdOut.println(time);
}
}
Why don't you hold a variable accumulatedTime and when the pause() method is called you append the accumulated time to it
accumulatedTime += System.currentTimeMillis() - start / 1000.0;
When resume() is called you could reset start
start = System.currentTimeMillis();
And then elapsedTime() would add the two:
public double elapsedTime() {
long now = System.currentTimeMillis();
return ((now - start) / 1000.0) + accumulatedTime;
}
You'd also need to track the paused state - a isPaused boolean instance variable perhaps? And then your pause()/resume() can response if appropriate
e.g. in pause() method:
if (isPaused) {
return; //do nothing
}
Paused time is stored in the additionaltime variable, this will be used to remove paused time when called elapsedTime. PauseStart variable stores when the pause is called(After resume call the additionaltime is calculated)
private long additionalTime;
private long pauseStart;
public void pause() {
if (pauseStart == 0) {
pauseStart = System.currentTimeMillis();
}
}
public void resume() {
if (pauseStart != 0) {
long stopTime = System.currentTimeMillis() - pauseStart;
additionalTime += stopTime;
pauseStart = 0;
}
}
public double elapsedTime() {
long now = System.currentTimeMillis();
if (pauseStart != 0) {
long stopTime = System.currentTimeMillis() - pauseStart;
additionalTime += stopTime;
pauseStart = 0;
}
return ((now - start) - additionalTime) / 1000.0;
}
It looks like your stopwatch is currently tied to the System time (System.currentTimeMillis()), so to pause the application you would need to subtract the time that you paused from your elapsed time somehow
What you could do though is to have save the time that you pause the clock, and what time it is resumed:
pause() {
if(!alreadyPaused)
timePaused = System.currentTimeMillis();
}
resume() {
timeResumed = System.currentTimeMillis();
totalTimePaused = previousPausedTimes + (timeResumed-timePaused);
}
and then in your elapsedTime():
public double elapsedTime() {
long now = System.currentTimeMillis();
return (now - start - totalTimePaused) / 1000.0;
}
Related
I have a custom timer that I'm keeping synced to the system clock. It's working fine for one minute intervals, but I also need it to sync to 36 second intervals (for updating fields when the user wants times displayed in decimal hours). Inside the Runnable I recalculate the adjustment (accurate enough for my needs) for the next minute, but can't find a way to conveniently deal with the different offsets needed for 36 seconds.
EDIT
private static class DecimalTimer extends TimerClass {
final int[] seconds = new int[101];
private boolean keepRunning = true;
private Runnable mRunnable;
#Override
void kill() {
keepRunning = false;
}
#Override
Runnable getRunnable() {
return mRunnable;
}
DecimalTimer() {
final int[] counter = new int[1];
for (int i = 0, j = 0; i < 3600; i += 36, j++) {
seconds[j] = i;
}
mRunnable = new Runnable() {
#Override
public void run() {
if (!keepRunning)
return;
final Calendar c = Calendar.getInstance();
int hourSeconds = c.get(Calendar.MINUTE) * 60 + c.get(Calendar.SECOND);
for (counter[0] = 0; counter[0] < 100; counter[0]++) {
if (seconds[counter[0]] > hourSeconds) {
c.add(Calendar.SECOND, seconds[counter[0]]);
break;
}
}
long adjustedDelay = (c.getTimeInMillis() - System.currentTimeMillis()) % 36000;
for (IntervalTimer listener : sListeners) {
listener.updateTime();
}
sHandler.postDelayed(this, adjustedDelay);
}
};
}
}
This edit fires every 36 seconds, but I need to get it to sync to 36 seconds on the clock (ie: 12:00:00, then 12:00:36 .. 12:01:12 .. 12:01:48)
Overthinking things as usual, this is what I came up with. It's accurate enough for what I need, but if anyone has an improvement for accuracy (It's a little off when it executes with 900ms or more) it'd be appreciated.
DecimalTimer() {
mRunnable = new Runnable() {
#Override
public void run() {
if (!keepRunning)
return;
final Calendar c = Calendar.getInstance();
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
do {
c.add(Calendar.SECOND, 36);
} while (c.getTimeInMillis() < System.currentTimeMillis());
long adjustedDelay = (c.getTimeInMillis() - System.currentTimeMillis()) % 36000;
for (IntervalTimer listener : sListeners) {
listener.updateTime();
}
sHandler.postDelayed(this, adjustedDelay);
}
};
}
Alright so I'm still kind of new with methods so forgive me if this seems out of whack. I have a homework problem that has to be a stop watch class with two private data fields startTime and endTime. I need a method named start() that resets startTime to the current time and then stop() that resets endTime to the current time. I also need a getElapsed time method and returns the value.
This is what I got so far:
public class stopWatch {
private double startTime;
private double endTime;
public static void main(String[]args) {
}
public stopWatch(double startTime) {
startTime = System.currentTimeMillis();
}
public void start() {
startTime = System.currentTimeMillis();
}
public void stop() {
endTime = System.currentTimeMillis();
}
public static void getElapsedTime(double startTime, double endTime){
stop() - start()
}
}
Could anybody please send me a step in the right direction? I know i need to subtract the start time from the stopped time and return that as the elapsed, I'm just not sure how to set it up properly.
Couple points.
startTime and endTime should be longs
Constructor should probably not take an argument.
start should probably set endTime to -1
getElapsedTime should be an instance method, not take arguments, return long and return endTime - startTime
to see it work, in your main, create a stopwatch, start the timer, call Thread.sleep(sometime), call stop, print out getElapsed.
I had to create the exact same thing. I wanted a simple Java stopwatch that would start running on my desktop. This is the code from the Stopwatch class. I added some formatting so it doesn't return long numbers that show how many milliseconds since you started the stopwatch. I assume that you would prefer to get something returned that is more meaningful to humans like seconds, minutes, and hours instead of milliseconds.
import java.text.DecimalFormat;
public class Stopwatch
{
// variables
private long startTime;
DecimalFormat twoDigits = new DecimalFormat("00"); // These help me return strings in the correct format
DecimalFormat threeDigits = new DecimalFormat("000"); // These help me return strings in the correct format
// Constructor
Stopwatch()
{
}
void start()
{
startTime = System.currentTimeMillis();
}
public long getStartTime()
{
return startTime;
}
public long getElapsedTime()
{
return System.currentTimeMillis() - startTime;
}
public String getElapsedTimeString()
{
return (String.valueOf(twoDigits.format(getHours())) + ":" + String.valueOf(twoDigits.format(getMinutes())) + ":" + String.valueOf(twoDigits.format(getSeconds())) + "." + String.valueOf(threeDigits.format(getMilliSeconds())));
}
public short getMilliSeconds()
{
return (short)((System.currentTimeMillis() - startTime) % 1000);
}
public byte getSeconds()
{
return (byte)(((System.currentTimeMillis() - startTime) / 1000) % 60);
}
public byte getMinutes()
{
return (byte)(((System.currentTimeMillis() - startTime) / 60000) % 60);
}
public long getHours()
{
return (System.currentTimeMillis() - startTime) / 3600000;
}
}
I am wondering the best way to keep a timer going in the background while a game is played.
I am programming a version of the HiLo game (in Java), which gives a user a certain amount of time to determine a number. If a guess is not correct, the game will tell the user whether the name is too high or too low.
I'm keeping track of time using System.currentTimeMillis() and seeing how much time has elapsed. This seems to work well, and so far I have been checking to see how much time has elapsed each time a new number is entered. For example, currently the app output looks like this:
Welcome to HiLo!
You have 10 seconds to guess a number I'm thinking of between 1 and 100.
> 67
Too high.
> 29
Too low.
Half of your time is gone! Only 5 seconds remains!
> 37
Too high.
> 33
Oops! Time is up - try again.
As you can see, currently, it can only check when I enter a new number how much time is passed.
I have tried creating a thread to start with a timer, however, when I start it, it keeps counting until the time is exhausted, without going on to the thread.run(int guess) which will be run when there is a new guess. I want to be able to still make guesses while the counter runs. Here is my attempt at a new implementation for thread.start():
public void start(int time_sent) throws InterruptedException {
time = time_sent;
startTime = (System.currentTimeMillis() / 1000);
while (1==1) {
long elapsed = ((System.currentTimeMillis() / 1000) - (startTime));
if (elapsed >= (time)) {
System.out.println("Oops! Time is up - try again.");
System.exit(0);
}
else if (elapsed >= (time/2) && !halfWarning) {
System.out.println("Half of your time is gone! Only " + (time/2) + " seconds remains!");
halfWarning = true;
}
}
}
How can I continue running this counter in the background?
This is one more approach:
public void game() {
Scanner scanner = new Scanner(System.in);
int time = 10; // sec
message("You have " + time + " seconds to guess...");
new Thread(new Background(System.currentTimeMillis() / 1000, time)).start();
while (true) {
String s = scanner.next();
if (s.equals("55")) {
message("You win");
System.exit(0);
} else {
message("try again...");
}
}
}
private void message(String str) {
System.out.println(str);
System.out.print("> "); // monit
}
You start 1 thread with behavior implemented in Background class. Next you enter while loop to capture user inputs. The Background thread works in background...
private class Background implements Runnable {
private long startTime;
private long time;
private boolean halfWarning;
private Background(long startTime, long time) {
this.startTime = startTime;
this.time = time;
}
#Override
public void run() {
while (true) {
long now = System.currentTimeMillis() / 1000;
long elapsed = now - startTime;
if (elapsed >= (time / 2) && !halfWarning) {
message("\n Half of your time is gone! Only " + (time / 2) + " seconds remains!");
halfWarning = true;
}
if (elapsed >= time) {
message("\n Oops! Time is up - try again.");
System.exit(0);
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
//ignore
}
}
}
}
Use a ScheduledExecutorService to execute concurrent actions in the future:
ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();
ScheduledFuture<?> half = ses.schedule(new Runnable() {
#Override
public void run() {
System.out.println("Half of your time is gone!");
}
}, time / 2, TimeUnit.SECONDS);
ScheduledFuture<?> full = ses.schedule(new Runnable() {
#Override
public void run() {
System.out.println("Oops! Time is up - try again.");
// System.exit(0) ?
}
}, time, TimeUnit.SECONDS);
// check
if (input == toGuess) {
half.cancel();
full.cancel();
}
You could have a Timer thread that prints out these messages and shuts down the listening program.
It might inspire you :
public static class Game extends TimerTask {
private long start;
private long end;
public Game(long end) {
super();
this.start = System.currentTimeMillis();
this.end = end;
}
#Override
public void run() {
while (System.currentTimeMillis() - start < end)
System.out.println(System.currentTimeMillis());
}
}
public static void main(String[] args) {
TimerTask task = new Game(10000);
Timer timer = new Timer();
timer.schedule(task,0);
}
how I can exit from a loop in one second using Runtime?
I want use this code
public class test {
public static void main(String[] args) {
Runtime runtime = Runtime.getRuntime();
long usedMemory = runtime.totalMemory()-runtime.freeMemory();
int mbytes = (int) usedMemory/1000; // Used memory (Mbytes)
String str="a";
while (somthing < one second ) {
}
}
long startTime = System.currentTimeMillis();
while((System.currentTimeMillis()-startTime)<=1000){
str=str + "a";
}
ok to do this you need to records the start time, and then compare it to the current time as you go.
long start = System.currentTimeMillis();
String str="a";
while (true) {
long now = System.currentTimeMillis();
if (now - start > 1000)
break;
// do your stuff
str=str + "a";
}
System.out.println (str);
The above code will probably spend more time getting the time that doing the stuff you want though
long startTime = System.currentTimeMillis();
while((System.currentTimeMillis()-startTime)<1000){
// Your task goes here
}
Write your code in while loop. It will exit the loop after 1 second.
long start = System.currentTimeMillis();
long end = start + 1000; // 1000 ms/sec
while (System.currentTimeMillis() < end)
{
// Write your code here
}
i think that you can use something like this if you don't really need to use Runtime.
public class test {
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
long currentTime = System.currentTimeMillis();
long usedMemory = runtime.totalMemory()-runtime.freeMemory();
int mbytes = (int) usedMemory/1000; // Used memory (Mbytes)
String str="a";
while (currentTime-startTime<1000) {
currentTime = System.currentTimeMillis();
}
}
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I found this stopwatch java code from somewhere on the Internet, but it does not seem to be working. I was wondering how to fix this code to make it work. It's supposed to have features to start, stop and reset, and should display the time as hours:minutes:seconds.milliseconds (example: 12:35:17.26). Please help me.
public class StopWatch {
private long startTime = 0;
private long stopTime = 0;
private boolean running = false;
public void start() {
this.startTime = System.currentTimeMillis();
this.running = true;
}
public void stop() {
this.stopTime = System.currentTimeMillis();
this.running = false;
}
//elaspsed time in milliseconds
public long getElapsedTime() {
long elapsed;
if (running) {
elapsed = (System.currentTimeMillis() - startTime);
}
else {
elapsed = (stopTime - startTime);
}
return elapsed;
}
//elaspsed time in seconds
public long getElapsedTimeSecs() {
long elapsed;
if (running) {
elapsed = ((System.currentTimeMillis() - startTime) / 1000);
}
else {
elapsed = ((stopTime - startTime) / 1000);
}
return elapsed;
}
//sample usage
public static void main(String[] args) {
StopWatch s = new StopWatch();
s.start();
//code you want to time goes here
s.stop();
System.out.println("elapsed time in milliseconds: " + s.getElapsedTime());
}
}
This example shows how to start and stop a javax.swing.Timer. Several approaches to formatting are shown here. Reset is left as an exercise.
By the level of your assignment, sounds like your professor wants you to use nested loops, which are not being used in the example you took from the web.
I won't give you the full answer, but it's fairly simple: outer-most loop is for hours, the one inside hours is for minutes, the one inside minutes for seconds, and the one inside seconds for milliseconds. The inner-most loop (milliseconds), is the one that prints the current time.
Something like this:
// 24 hours in a day
for(int hours = 0; hours < 24; hours++)
{
// 60 mins in an hours
for(int minutes = 0; minutes < 60; minutes++)
{
// 60 secs in a min
for(int seconds = 0; seconds < 60; seconds++)
{
// 1000 ms in a sec.
for(int ms = 0; ms < 1000; ms++)
{
System.out.println(hours + ":" + minutes + ":" + seconds + "." + ms);
}
}
}
}
Now make it pretty and add a 1-millisecond delay in the inner-most loop and you are done! :)
If you want to make a stopwatch you must make a Thread. The Java API states all of the functions of a thread. This is necessary, because otherwise you won't be able to pause the timer. This is because the system spends the full runtime on the counting.
Also, the script you provided is used for determining the amount of time a certain calculation took, it's not ment for timing itself.
I suggest you make 2 classes, 1 for the timer and 1 for the GUI. make the GUI with a label, a start-, stop- and reset-button.
Next, make sure the timer-class EXTENDS THREAD (or implements Runnable) and make it a thread. Next implement the functions to either stop the thread or start the thread (your start/stop buttons). The Reset should be easy after that (just set the timer back to 0).
The StopWatch-class could look like this:
public class Stopwatch extends Thread
{
private long startTime;
private boolean started;
public void startThread()
{
this.startTime = System.currentTimeMillis();
this.started = true;
this.start();
}
public void run()
{
while (started)
{
// empty code since currentTimeMillis increases by itself
}
}
public int[] getTime()
{
long milliTime = System.currentTimeMillis() - this.startTime;
int[] out = new int[]{0, 0, 0, 0};
out[0] = (int)(milliTime / 3600000 );
out[1] = (int)(milliTime / 60000 ) % 60;
out[2] = (int)(milliTime / 1000 ) % 60;
out[3] = (int)(milliTime) % 1000;
return out;
}
public void stopThread()
{
this.started = false;
}
}
In the GUI-class you would make start call the 'startThread', stop call the StopWatch.stop(); (which is a Thread-function) and make reset call the reset().
This should get you started with a basic stopwatch. A (bad) example for its useage:
public static void main(String[] args) throws InterruptedException
{
Stopwatch s = new Stopwatch();
s.startThread();
while (true)
{
int[] curTime = s.getTime();
System.out.println(curTime[0] + " : " + curTime[1] + " : " + curTime[2] + " : " + curTime[3]);
}
}
It would actually be more sensible to do the calculations on the currentTimeMillis outside of the threadclass.