I am trying to creating countdown timer using java with Netbeans 8.1 IDE,, My problem is when the timer gets 00:00 it do not want to stop..I have trying to write timer.stop(); but it still not working...Maybe you can help me ..
this is my source code :
ActionListener action;
action = new ActionListener() {
public void actionPerformed(ActionEvent e) {
seconds--;
if(seconds==0){
minutes--;
seconds=60;
}
if(seconds==0 && minutes==0){
timer.stop();
}
String min = minutes <= 9? "0"+minutes:minutes+"";
String seg = seconds <= 9? "0"+seconds:seconds+"";
txtRemaining.setText(min+":"+seg);
}
};
this.timer = new Timer(interval, action);
this.timer.start();
Your problem is here:
if(seconds==0 && minutes==0){
timer.stop();
}
seconds can never == 0 here since just before this block of code you call:
if(seconds==0){
minutes--;
seconds=60;
}
and if seconds == 0, you set it immediately to 60. The solution is to swap these two lines:
// call this **first**
if(seconds==0 && minutes==0){
timer.stop();
}
// call this **second**
if(seconds == 0){
minutes--;
seconds = 60;
}
Related
I am struggling with wierd issue, I've made countdown timer with round progressbar. Sometimes as the time runs out, there is few pixels of progressbar left (orange between x and t), even though it reaches onFinish function. It's not a problem no more as I set countDownInterval to 10, but then showProgress function doesn't quite work, it enters else statement, but doesn't actually set progressbar to 0.
private void startCountingTime() {
if (!counting) {
timeLeftInMillis = maxTime * 1000;
endTime = System.currentTimeMillis() + timeLeftInMillis;
}
if (maxTime != 0) {
countDownTimer = new CountDownTimer(timeLeftInMillis, 100) {
#Override
public void onTick(long l) {
String text = String.format(Locale.getDefault(), "%02d:%02d",
TimeUnit.MILLISECONDS.toMinutes(l) % 60,
TimeUnit.MILLISECONDS.toSeconds(l) % 60);
timeLeftInMillis = l;
showProgress(l, maxTime);
counting = true;
question.setText(exposePasswd ? text : currentQuestion);//displays the timer or question
}
#Override
public void onFinish() {
step = 4;
counting = false;
progressBar.setProgress(0);
question.setText("Out of time! doubletap for next question");
}
}.start();
} else {
question.setText("tap to reveal, doubletap for next");
exposePasswd = false;
}
}
private void showProgress(long l, int maxTime) {
maxTime = maxTime * 1000;
int prog = (int) ((l * 100) / maxTime);
if (exposePasswd) {
// progressBar.setVisibility(View.VISIBLE);
if (progressBar.getProgress() == 0) {
progressBar.setProgress(prog);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
progressBar.setProgress(prog, true);
} else {
progressBar.setProgress(prog);
}
} else {
progressBar.setProgress(0);
Log.wtf("idk","setted");
}
}
Any ideas how to fix it?
Im not sure, why this is happening, but you could probably easily bypass this issue by adding:
progressbar.setVisibility(Visibility.GONE);
in the else statement and
progressbar.setVisibility(Visibility.VISIBLE);
when the timer starts.
For my code I use a countdown timer, however I add seconds to it as after they get an answer correct, the timer is reset to 5 seconds. The problem with this is that the text that displays the time still has the wrong number, it doesn't repeat digits. For instance if it was a 5 second timer and it goes 5,4,3 then the user gets it right, the time will go 3, 3, 3, 2, 1.
Here is my countdown code
n = 5000;
time = new TextView(this);
time.setTextColor(Color.parseColor("#FFFFFF"));
timer = new CountDownTimer(n, 1000) {
public void onTick(long millisUntilFinished) {
time.setText("seconds remaining: " + millisUntilFinished / 1000);
}
public void onFinish() {
Intent endIntent = new Intent(MainActivity.this, Endgame.class);
endIntent.putExtra("rounds",round);
MainActivity.this.startActivity(endIntent);
}
}.start();
Then if the user gets the question right - this is the part that restarts it
if(person == false){
picturechanger();
n=5000;
timer.onTick(5000);
}
Try:
if(person == false){
picturechanger();
n=5000; // Not sure why u put n=5000 here..?
if(timer != null)
timer.cancel();
timer.start();
}
Ok so I have created a game and it works perfectly, except I don't want the player to win after just one defeat I want him to have to kill 10 enemies well I created my spawnmore method and I know the problem I just don't know how to fix it, in my if statement I have it saying if(dead < 10) then do my stuff, when I only want it to do it once every time dead increments one if you get what I mean here's my method thanks
public void spawnMore(){
int delay = 1000;
Timer time = new Timer(delay, new ActionListener(){
public void actionPerformed(ActionEvent e){
if(WizardCells[BadGuy.getx()][BadGuy.gety()].getIcon() != null){
return;
}
if(WizardCells[BadGuy.getx()][BadGuy.gety()].getIcon() == null){
dead += 1;
}
if(dead < 10){
int where = (int)(10 + Math.random() *9);
BadGuy.spawnEnemy(where, where);
move();
}
}
});
time.start();
}
If I understand you correctly, you could just move the if statement inside the previous if statement:
public void spawnMore(){
int delay = 1000;
Timer time = new Timer(delay, new ActionListener(){
public void actionPerformed(ActionEvent e){
if(WizardCells[BadGuy.getx()][BadGuy.gety()].getIcon() != null){
return;
}
if(WizardCells[BadGuy.getx()][BadGuy.gety()].getIcon() == null){
dead += 1;
if(dead < 10){
int where = (int)(10 + Math.random() *9);
BadGuy.spawnEnemy(where, where);
move();
}
}
}
});
time.start();
}
Hi I want to run code over a time period. For example i would like my code to do something like this.
for(every 5 minutes until i say to stop)
automatically read in new value for x
automatically read in new value for y
if (x==y)
//do something
if (x!=y)
//do something else
Timer is what you need.
Naive version. You might consider Timer or the quartz scheduler instead.
while (!done) {
try {
Thread.sleep(5 * 60 * 1000);
x = readX();
y = readY();
if (x == y) {
} else {
}
} catch(InterruptedException ie) {
}
}
System.currentTimeMillis(); Returns you the system time in milliseconds, you can use that.
but first, you need some sort of loop.
This is an alternative to Timer 's
public static final int SECONDS = 1000;
public static final int MINUTES = 60 * SECONDS;
boolean quit = false; //Used to quit when you want to..
long startTime = System.currentTimeMillis();
while (!quit) {
if (System.currentTimeMillis() >= (startTime + (long)5*MINUTES)) {
//automatically read in new value for x
//automatically read in new value for y
if (x==y) {
//do something
} else {
//do something else
}
startTime = System.currentTimeMillis(); //reset the timer for the next 5 minutes
}
}
How about:
Runnable runnable = new Runnable() {
public void run() {
// do your processing here
}
};
ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
service.scheduleAtFixedRate(runnable, 0, 5, TimeUnit.MINUTES);
Call service.shutdown() when you want to stop.
I have a milliseconds and i convert it hh:mm:ss now i want to make it to automatically decrease value overtime.. something like countdown timer
for example, when user sees it, 2:11 0 -> 2:10 59 -> 2:10 58 ...
Below is my code..
Timer t = new Timer(1000, new ActionListener() {
public void actionPerformed(ActionEvent e) {
int s = ((TIMER/1000) % 60);
int m = (((TIMER/1000) / 60) % 60);
int h = ((((TIMER/1000) / 60) /60) % 60);
timing.setText(hour + " hours, " + min + " minutes" + sec + " seconds");
timing.repaint();
}
}
t.start();
is it possible?
final Timer t = new Timer(1000, new ActionListener() {
private long time = 10 * 1000; //10 seconds, for example
public void actionPerformed(ActionEvent e) {
if (time >= 0) {
long s = ((time / 1000) % 60);
long m = (((time / 1000) / 60) % 60);
long h = ((((time / 1000) / 60) / 60) % 60);
timing.setText(h + " hours, " + m + " minutes " + s + " seconds");
time -= 1000;
}
}
});
t.start();
As Peter mentioned in his answer, you shouldn't relay on decreasing a number, since there are not guarantees that actionPerformed is invoked right in every second. The below is a working example, which stops the timer on finishing (detailed and therefor code):
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Test extends JFrame {
private JTextField text;
private Timer timer;
private JButton start;
public Test() {
super("Countdown timer");
text = new JTextField("2", 8);
start = new JButton("Start");
start.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent click) {
final long current = System.currentTimeMillis();
try {
final long limit = Integer.parseInt(text.getText().trim())* 1000; // X seconds
timer = new Timer(1000, new ActionListener() {
public void actionPerformed(ActionEvent event) {
long time = System.currentTimeMillis();
long passed = time - current;
long remaining = limit - passed;
if(remaining <= 0) {
text.setText("2");
timer.stop();
} else {
long seconds = remaining/1000;
long minutes = seconds/60;
long hours = minutes/60;
text.setText(String.format("%02d:%02d:%02d", hours, minutes, seconds%60));
}
}
});
timer.start();
} catch(NumberFormatException nfe) {
// debug/report here
nfe.printStackTrace();
}
}});
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
panel.add(text);
panel.add(new JLabel(" seconds"));
panel.add(start);
add(panel);
}
public static void main(String [] args) throws Exception {
Test frame = new Test();
frame.setDefaultCloseOperation(Test.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}
The TIMER value is never decremented by the timer event. Therefore the same time will always be displayed every 1000 milliseconds.
Edit: Assuming "timing" is a Swing component the call to repaint should be unnecessary.
A safer option is to take the actual clock time. The reason for this is that your application can stop for pewriods of time. esp if you machine is busy. This means a countdown timer might not be called as often as you expect. If you use the System.currentTimeMillis() the time will always be right no matter what happens.