Java StopWatch in ChessGame - java

I have two threads in my ChessGame and I want to implement time control:
Turn of first player: second_thread.stop(), first_thread.run();
counterOfSteps++;
Turn of second player: first_thread.stop(), second_thread.run();
counterOfSteps++;
I have founded many information about Timer but I need Threads.Second thread the same.
There is my code of first thread and it doesn't work because time isn't stopped (System.currentTimeMillis)
first = new Thread() {
#Override
public void run() {
final long time = System.currentTimeMillis();
final long duration = 10800000; //3 hours
while (true) {
try {
Thread.sleep(100);
if (counterOfSteps % 2 == 0) {
System.out.println("Time" + ((duration - (System.currentTimeMillis() - time)) / 1000) % 60);
}
} catch (InterruptedException ex) {
LOG.log(Level.SEVERE, "Unexpected interrupt", ex);
}
}
}
};
How to solve this problem?
Update:
I don't use .stop(). I wrote is for example how to realize.

I have founded many information about Timer but I need Threads.
No. If all you are trying to do is implement a chess clock, then you don't need threads for that. A Timer task that wakes up every second (or every 1/10 second) can;
look at whose turn it is (e.g., counterOfSteps % 2),
compute how much time that player has used, and
Update the appropriate text box in the GUI.
To compute how much time, it'll need to know three things;
What time it is now (e.g., System.currentTimeMillis()),
What time it was when the current turn started, and
How much time the player already had on the clock when the current turn started.
There is no way to pause the system clock (i.e., System.currentTimeMillis()), but that's not a problem. If you sample the clock at the start of each turn, then you can compute the duration of the current turn as System.currentTimeMillis() minus the start time.

I used this example for my quiz, i have 10sec do answer on question this timer decrease int t every 1sec, and set how many times left in some JLabel. You can make 2 object of Timer, first object for first player and second object for second player. You can stop timer when someone finish the move and start second timer...
int t=10
lb2=new JLabel(t);
tim=new Timer(1000,new ActionListener(){
#Override
public void actionPerformed(ActionEvent e){
if(t>0){
t--;
lb2.setText(String.valueOf(t));
}else{
tim.stop();
JOptionPane.showMessageDialog(null, "Time is up");
}
}
});
}

Related

Keeping timer events equally spaced

I'm attempting to get an animation working in a game I'm developing. The animation works by setting a button size to very small, then gradually growing it to its normal size again. I have it working, except I'm having timing issues.
Sometimes the button will grow almost instantly, sometimes it goes VERY slow. I'm looking for something inbetween, and I need it to ALWAYS grow at that size, not some times fast sometimes slow.
I've looked into it and I found this pseudocode:
distance_for_dt = speed * delta_time
new_position = old_position + distance_for_dt
Unfortunately I don't understand what's being said, and I don't know how to apply this to my code. Can anyone help with that or explain what's being said in the above pseudocode?
Here's my timer code, timer is already defined above as a Timer, and z[] is just a pair of coordinates:
timer = new Timer(18, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Dimension dim = button[z[0]][z[1]].getSize();
if (dim.getHeight() < 79.9) {
button[z[0]][z[1]].setSize((int) (dim.getWidth() + 6), (int) (dim.getHeight() + 6));
} else {
button[z[0]][z[1]].setSize(80, 80);
timer.stop();
}
}
});
timer.start();
Depending on how many updates you're calling on your Swing application, it may be getting "backed up" and slowing down. For instance, if you wanted to accomplish the animation without a Timer, you could just do something like this:
// example method to do animation
public void animateButton(final int wait){
Thread thread = new Thread(){
public void run(){
// some loop structure to define how long to run animation
Dimension dim = button[z[0]][z[1]].getSize();
while (dim.getHeight() < 79.9){
SwingUtilities.invokeLater(new Runnable(){
//update Swing components here
});
try{ Thread.Sleep(wait); }
catch(Exception e){}
}
}
}
}
thread.start();
}
I think this may be similar to how a Timer updates the GUI, as Timers run on a separate thread. I would look into whether or not you need to use invokeLater(new Runnable) inside a timer to properly schedule the task. I had to do this to allow a project I was working on to keep responsive during long tasks. If you really needed to ensure the speed and maybe DROP updates to adjust for system lag, then you'll need to be calculating how complete the animation is vs how much time has passed, using a method call such as System.currentTimeMillis() or System.nanoTime(). Then, adjust accordingly for each step of the animation.

Nesting of timers

This post is related to my last post.The block of code changes the text to desired color after desired time.
however, now I want to change the color of a perticular word such that each letter gets the equal time.EG if "hello" have been given a time of 1000 milliseconds (have 5 letters) then 'h''e''l''l''o' each letter should get 1000/5 milliseconds i.e 200 milliseconds each.
I implemented swing timer for this :
public Reminder() {
a[0]=2000;
a[1]=1000;
a[2]=3000;
a[3]=5000;
a[4]=3000;
ActionListener actionListener = new ActionListener() {
public void actionPerformed(ActionEvent actionEvent) {
point =point +arr[i].length();
i++;
doc.setCharacterAttributes(0,point+1, textpane.getStyle("Red"), true);
timer.setDelay(a[i]);
}
};
timer = new Timer(a[i], actionListener);
timer.setInitialDelay(0);
timer.start();
For this to happen, shoud I use another Timer inside the actionListener to give further timings to a perticular letter?Or should I first break the time by .length()
and then use the timer?I cannot decide a better way.Any ideas?
You should never need more than one timer. Since you know ahead of time exactly when everything should happen, just calculate those times, put them in a list (sorted by time) and execute each one.
public colorize(int offset, int length) {
long triggerTime[] = new long[length];
long startTime = System.currentTimeMillis();
for (int i=0; i<length; i++) {
triggerTime[i] = startTime + (1000*i)/length;
}
for (int i=0; i<length; i++) {
//just wait for the next time to occur
Thread.sleep(triggerTime[i]-System.currentTimeMillis());
doc.setCharacterAttributes(offset, i+1, textpane.getStyle("Red"), true);
}
}
This may strike you as very pedestrian because it does not use a TimerTask object, but it is effective, efficient, and easy to debug. You simplty call this method on whatever thread you want, and it occupies the entire thread, and the word will be colorized at a rate such it is completed in 1 second.
You could, if you don't have a thread handy, make a timer that calls this, but the only reason for that is to access a thread. The real point is: don't set up multiple timers, just make an array of time values. After one event is satisfied, set to delay until the next time. You never need multiple timers.
It would be a little cleaner if you made an object that represented the coloring of a character (or whatever action you want) and you put together a collection of these actions. Then sort the entire collection by time they are to go off. The loop above would walk through the collection, waiting until the time for the action arrives, and then executing it. Another advantage of this approach is that you could clear the collection and that would terminate the loop.
See the discussion of the overuse of timers on my website to understand why this is bad.

I want to add timer in my applet

I made CountDown.java file and try to add in my Word-trouble.java file (which is main applet) as CountDown ct = new CountDown();
but it is not showing timer in main applet.
Here is coding:
package pack.urdu;
import java.awt.*; //windows toolkit
import java.applet.*; //applet support
public class CountDown extends Applet implements Runnable{
int counter; Thread cd;
public void start() { // create thread
counter = 60; cd = new Thread(this); cd.start();
}
public void stop() { cd = null;}
public void run() { // executed by Thread
while (counter>0 && cd!=null) {
try{Thread.sleep(1000);} catch (InterruptedException e){}
--counter; repaint(); //update screen
}
}
public void paint(Graphics g) {
g.drawString(String.valueOf(counter),25,75);
}
}
You are making a mistake that I see a lot of programmers make: you are mixing up the calculation of elapsed time, with the calculation of the refresh time. If the duration of sleep takes long than a second because of thread contention, your timer will drift.
Instead of tracking a counter that increments every second, just record the start time:
long startTime = System.currentTimeMillis();
Then later, your paint method becomes:
public void paint(Graphics g) {
int elapsedSeconds = (int)(System.currentTimeMillis()-startTime)/1000
g.drawString(String.valueOf(elapsedSeconds),25,75);
}
This method can be called as often, and as many times as you like, and it will always display the correct elapsed seconds. There is no need to increment anything at any specified time.
The only other thing you have to do is to arrange that the screen gets refreshed. (I like to say that you only have to refresh the screen when the user looks at it :-) but since we don't know that we need to refresh more often). The mechanism for this may depend upon the graphic library. One lazy idea is to refresh ten times a second and the screen will be right most of the time.
If you do want to have a thread that sends repaint events, you should have those events sent just at the time that timer clicks over to a new value, and thereby send only one per second. This is done with:
while (stillRunning) {
long elapsedTime = System.currentTimeMillis() - startTime;
long timeTillNextDisplayChange = 1000 - (elapsedTime % 1000);
Thread.sleep(timeTillNextDisplayChange);
repaint();
}
Note that you do not sleep 1000ms! If your system is performing well, this will be very close to 1000ms, but slightly less than that to account for (1) the thread startup delay, possibly caused by thread contention, and (2) the processing time for this loop (which is quite small). In any case, calculating the sleep in this way will prevent timer drift, and assure that your display updates just as the seconds value changes.
See an extended discussion of Common Misunderstandings of Timers on my website.

With each successive call to this `timerMethod` , timerInt's value increases faster than before

I am working on an app, which gets a sort of restart with an event. On the first run, the timer works perfect (1sec = 1 increment). but, on next run (1sec = 2 increment) on third run (1sec = 4 increment) and so on...
I think there is something wrong with the new TimerTask object being created. but, dunno how to handle it. any suggestion or alternate ?
CODE SNIPPET:
Timer t = new Timer();
void timerMethod()
{
t.schedule(new TimerTask() {
public void run() {
timerInt++;
//TODO bug in timer in consecutive runs. To confirm, see log
Log.d("timer", "timer " + timerInt);
/* runOnUiThread(new Runnable() {
#Override
public void run() {
timerDisplayPanel.setText( timerInt + " Sec");
}
});*/
}
}, 1000, 1000);
}
It sounds like you're calling timerMethod() multiple times.
When you've called it three times, you've got three timer tasks scheduled - so they'll all fire each second, and all increment timerInt. You either need to not call it multiple times, or cancel the existing timer tasks before adding more.
If that's not the case, please provide a short but complete program to show what's happening. The context is fairly vague at the moment.
The snippet you provided is working properly
1 sec 1 increment
2 sec 2 increment
3 sec 3 increment
etc
So probably the problem is somewhere else in your code.

Recurring Countdown Timer in Java

I'm trying to implement a countdown timer into a pre-existing public class and I have a few questions.
An overview: I want to have a timer within a program that counts down from 60 (seconds) once the program is initialized.
If the timer reaches zero, the program quits.
If the user meets certain parameters within the 60 second time frame, the timer resets to 60, presents a new set of parameters, and begins the countdown again. It should be able to do this an infinite number of times, until the user fails to meet parameters within 60 seconds.
There will also be some sort of (TBD) GUI representation of the timer, most likely either numerical countdown or JProgressBar.
I'm semi-new (~3 months) to programming, self-taught, and still learning lots (so be gentle) :)
My questions are:
What is the best way to implement this?
I'm assuming this needs to run in a thread?
Will the timer be easily configurable? (not important, just interesting)
Thanks for your help. If you need to see code, I can find some.
EDIT: Just for some clarification/context:
This is for a timed racing video game I'm working on to develop my skills as a programmer. The idea is that a player has 60 seconds to complete a lap. If the player completes a successful lap, the timer resets to 60 seconds and the track changes to be slightly more difficult. The game runs until the player is unable to complete a lap in 60 seconds due to the difficulty. The game records the number of laps as a high score, and asks to player if they would like to try again.
If I were you, I'd use:
an AtomicInteger variable which would keep the current countdown value;
a timer thread that would wake up every 1s and decrementAndGet() the variable, comparing the result to zero and terminating the app if the result is zero;
(possibly) a thread that would also wake up every 1s to repaint the GUI -- the best approach here depends on your GUI framework.
Finally, whenever you need to reset the count back to 60s, you just call set(newValue) from any thread.
The timer thread's run() method could be as simple as:
for (;;) {
if (counter.decrementAndGet() <= 0) {
// TODO: exit the app
}
Thread.sleep(1000);
}
I think it's much easier to get this right than trying to manage multiple Timer objects.
The best way to impliment timer in your application is using some sheduler frameworks like Quartz
You could use java.util.Timer to schedule an execution of a method and then cancel it if the requirements is met.
Like this:
timer = new Timer();
timer.schedule(new Task(), 60 * 1000);
And then make a class like this to handle the timerschedule:
class Task extends TimerTask {
public void run() {
System.exit(0);
}
}
If the requirements is met, then do this to stop it from executing:
timer.cancel();
If you need to update your GUI better to use SwingWorker http://en.wikipedia.org/wiki/SwingWorker
I would write something like this:
SwingWorker<String, Integer> timer = new SwingWorker<String, Integer>() {
Integer timer=60;
#Override
protected String doInBackground() throws Exception {
//update guiModel
//label.setText(timer.toString());
while(timer>0){
Thread.sleep(1000);
timer--;
}
return null;
}
#Override
public void done(){
System.exit(0);
}
};
JButton restart = new JButton(){
{
addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
timer.cancel(true);
timer.execute();
}
});
}
};

Categories

Resources