I'm writing a "Who Wants to Be a Millionare" game and I have everything set up, it's just a problem with the timer.
The game works like this: if the user gets the question right he/she moves on. If not, the game is over and they can opt to play again.
When the game first runs it's fine and the timer does what it should -- start at 30 seconds and count down, displaying the seconds.
However, when the user clicks the "play again" button, the previous timer continues with the new timer. Like this:
-timerA had 20 seconds left before the user lost (indicated by a).
-timerB begins the next time the game is played (indicated by b).
output: 20a 29b 19a 28b 18a 27b 17a 26b ....... 2a 11b 1a 10b 9b 8b 7b 6b 5b 4b 3b 2b 1b
So here is my timer class called CountDown:
import java.util.Timer;
import java.util.TimerTask;
public class CountDown {
static Timer timer;
public static int seconds = 30;
public CountDown() {
timer = new Timer();
timer.schedule(new DisplayCountdown(), 0, 1000);
}
class DisplayCountdown extends TimerTask {
int seconds = 30;
public void run() {
if (seconds == 0) {
timer.cancel();
timer.purge();
return;
}
if (seconds > 0) {
PlayFrame.timer.setText("" + seconds); //jLabel used to display seconds
seconds--;
if (seconds < 30) {
if (PlayFrame.right == true) { //check if question was answered correctly
System.out.print("true"); //testing purposes
PlayFrame.right = false;
PlayFrame.showQuestion();
PlayFrame.startTimer();
seconds = 0;
//break;
}
else if (PlayFrame.right == false) {
//break;
}
}
else if (seconds == 0) { //if time runs out its automatic wrong answer
PlayFrame.wrong();
//break;
}
else {
PlayFrame.wrong();
PlayFrame.timer.setText(null);
timer = new Timer();
//break;
}
}
System.out.println(seconds); // for testing purposes only
}
}
}
and here is some of my PlayFrame:
import java.awt.Color;
import java.util.Timer;
public class PlayFrame extends javax.swing.JFrame {
public static void wrong() {
//determines which losing frame to show
if (count <= 2){
LossLevel0 L0 = new LossLevel0();
L0.setVisible(true);
}
else if (count > 2 && count <= 6 && count != 6){
LossLevel1 L1 = new LossLevel1();
L1.setVisible(true);
}
else {
LossLevel1 L1 = new LossLevel1();
L1.setVisible(true);
}
//"supposed" to stop the timer
CountDown.timer.cancel();
CountDown.timer.purge();
}
public static void startTimer() {
//creates new CountDown object and timer, also resets seconds
CountDown countdown = new CountDown();
CountDown.timer = new Timer();
CountDown.seconds = 30;
}
I think the trouble may be in when I restart the game. The only code that is in there is I reset all of my variables back to its original state before the game started. Like so:
// Reset Everything
PlayFrame.count = 0;
PlayFrame.answer = new String();
PlayFrame.count = 0;
PlayFrame.right = false;
PlayFrame.winnings = 0;
CountDown.seconds = 30;
CountDown.timer = new Timer();
CountDown.timer.cancel();
CountDown.timer.purge();
Please help, and if you need further information just ask!
You shouldn't be using java.util.Timer with a Swing application. For these you should use javax.swing.Timer since this will respect the Swing event thread. Thus your question is moot, and I suggest that you throw all of your timing code out and try the proper timer. You can find the tutorial here: Swing Timer Tutorial
Next you'll want to get rid of all the static methods and fields that your code is using and change them over for instance fields and methods.
An example of a Swing Timer displaying remaining time in a JLabel:
Solved, thanks for the link sage88! http://albertattard.blogspot.com/2008/09/practical-example-of-swing-timer.html
And for more help on swing timers (for future searches of this topic) http://www.asjava.com/swing/java-timer-tutorial/
What I recommend doing is moving the Timer declaration into the JFrame, and then creating a new instance of your "DisplayCountdown" class for each time the timer is needed, and move the "timer.schedule(new DisplayCountdown(), 0, 1000);" line elsewhere.
If you purge a timer object, it is completely reset, so you don't need to create a new timer object, only add a new TimerTask.