//I am trying to set a timer for my minesweeper code using java, and below is my code for timer setting. It is supposed to be a 1000sec countdown, but somehow, the program will sometimes refresh and start over from 1050sec itself, which is very confusing. Can anyone help me to resolve the issue?
public Board(JLabel timeBar, JLabel statusBar) {
...
startTime = LocalDateTime.now().getSecond();
// set timer
timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
if (!gameOver) {
int endTime = LocalDateTime.now().getSecond();
int delta = endTime - startTime;
if (delta >= 1000) {
gameOver = true;
} else {
timeBar.setText(String.format("Time Remaining: %d", 1000 - delta));
}
}
}
}, 1000, 1000);
}
Related
I have a Timer in my Code, but the debugger jumps not into it. When it arrives at "timer.schedule()", jumps directly behind it and is not instancing the anonymous TimerTask. Can anyone help me why?
CODE:
timer = new Timer();
lastTimestamp = calendar.getTimeInMillis() / 1000;
// WHEN DEBUGGING IT JUMPS FROM THIS LINE
timer.schedule(new TimerTask() {
#Override
public void run() {
long now = calendar.getTimeInMillis() / 1000;
secondsElapsed += now - lastTimestamp;
lastTimestamp = now;
// Abbruch-Bedingung
if(secondsElapsed == totalSeconds)
{
// TODO:
Log.d("MainActivity", "Zeit abgelaufen");
}
else
{
int minutes = (int)secondsElapsed / 60;
int seconds = secondsElapsed - (minutes * 60);
final String newValue = String.format("%02d:%02d", minutes, seconds);
runOnUiThread(new Runnable() {
#Override
public void run() {
timerText.setText(newValue);
}
});
}
}
}, 0, 1000);
// TO THIS LINE
Those lines are executing in another thread. When that thread is scheduled to run they will run. If you place a breakpoint there you will see them execute
EDIT
try {
Timer timer = new Timer();
long lastTimestamp = System.currentTimeMillis() / 1000;
// WHEN DEBUGGING IT JUMPS FROM THIS LINE
timer.schedule(new TimerTask() {
#Override
public void run() {
System.out.println("WWWWWWW");
}
}, 0, 1000);
}
catch(Exception x){
}
}
This code executes with no problem. The thread is executed inside the timer
I need to to show a countdown timer with 2 time periods, for example i need it to count down a 45 sec, then count down 15 sec and then loop it all over again 4 times.
I tried this code but it seems to start all the timers at ones. I want at to start the first timer and wait till it finish and then start the second timer wait till it finish and then loop it again.
what should i do??
for (int i = 0; i < labsNum; i++) {
currLabTV.setText("LAB " + (i + 1));
if(isWorking) {
timer = new WorkCounter(workNum * 1000, 1000);
timer.start();
}
if(!isWorking){
timer = new WorkCounter(restNum * 1000, 1000);
timer.start();
}
}
i extended the CountDownTimer class.
public class WorkCounter extends CountDownTimer {
public WorkCounter(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
#Override
public void onTick(long millisUntilFinished) {
String ms = String.format("%02d:%02d" , TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished), TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished));
timeTV.setText(ms);
}
#Override
public void onFinish() {
if(isWorking) {
workoutSign.setText("REST");
}else {
workoutSign.setText("WORKOUT");
}
isWorking = !isWorking;
}
}
I created an application that can call using our SIP server. Now I want to do is to show the user how long his call has been on going. My script is actually working but I noticed that the longer the call, the laggy my app becomes. Here's the snippet of my code
Handler h = new Handler(Looper.getMainLooper());
_isOnCall = true;
long time = 0;
int x = 0;
while(_isOnCall) {
if (_isOnCall){
final int counter = 1 + x;
time += 1000;
h.postDelayed(new Runnable() {
#Override
public void run() {
(TargetDetailsActivity.this).runOnUiThread(new Runnable() {
#Override
public void run() {
final int seconds = counter % 60;
final int minutes = (counter % 3600) / 60;
final int hours = counter / 3600;
callcounter.post(new Runnable() {
#Override
public void run() {
callcounter.setText(String.format("%02d:%02d:%02d", hours, minutes, seconds));
}
});
}
});
}
}, time);
x++;
}else{
break;
}
}
Basically what the code does is just to count the seconds/minutes/hour he's been on the phone. When he hangs up, I call the code below:
_isOnCall = false;
h.removeCallbacksAndMessages(null);
I'm not sure what causes the lag. Help! Thanks.
UPDATE
I was able to make this working by utilizing galvan's suggestion using Timer. Here's my code for future reference:
private Timer myTimer;
private int counter_time=0;
public void onCallEstablished() {
myTimer = new Timer();
myTimer.schedule(new TimerTask() {
#Override
public void run() {
TimerMethod();
}
}, 0, 1000);
}
private void TimerMethod()
{
this.runOnUiThread(Timer_Tick);
}
private Runnable Timer_Tick = new Runnable() {
public void run() {
counter_time++;
int seconds = counter_time % 60;
int minutes = (counter_time % 3600) / 60;
int hours = counter_time / 3600;
callcounter.setText(String.format("%02d:%02d:%02d", hours, minutes, seconds));
}
};
public void releaseCall(){
if(myTimer != null){
myTimer.cancel();
myTimer.purge();
counter_time = 0;
}
}
It looks like every Runnable saves a reference to his parent object, a nested Runnable in this case. Try to take an heap snapshot for detecting a memory issues to see if this is the case here.
You can also make a repeat task with time interval, and stop the loop when the call ends.
Timer timer = new Timer();
TimerTask myTask = new TimerTask() {
#Override
public void run() {
// whatever you need to do every 2 seconds
}
};
timer.scheduleAtFixedRate(myTask,
firstTime,
period);
for more info about timer you can take a look at the docs
I'm trying to make a stopwatch that constantly updates to the screen what the time is. The time object is a JLabel that should display the time elapsed. I have everything imported and set up right, but whenever the start button is clicked to activate the timer, the program freezes.
public class Timing
{
public void Timer()
{
startTime = System.currentTimeMillis();
while(isTiming == true)
{
endTime = System.currentTimeMillis();
elapsedTime = endTime - startTime;
time.setText("" + elapsedTime);
info.validate();
}
endTime = System.currentTimeMillis();
elapsedTime = endTime - startTime;
time.setText("" + elapsedTime);
info.validate();
}
}
Here's the Action Listener part:
public void actionPerformed(ActionEvent arg0)
{
if(((JButton) arg0.getSource()).getText().equals("Start"))
{
isTiming = true;
new Timing().Timer();
}
You are trying to synchronously update your label in a loop in the UI thread, the same thread which is used for applying UI updates. By doing this you are blocking the execution which results into the freeze you are describing.
To resolve this, you could use the javax.swing.Timer to schedule the updates so that they would be run in the same UI thread, but only when needed, i.e.
timer = new javax.swing.Timer(10, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
...
time.setText("" + elapsedTime);;
}
});
...
public void actionPerformed(ActionEvent arg0)
{
if(((JButton) arg0.getSource()).getText().equals("Start"))
{
isTiming = true;
timer.start();
}
}
I have a fairly simple JavaFX GUI application which has an label that shows how much time is left until a certain action starts. To achieve this, I've created a DownloadTimer class as shown below:
public class DownloadTimer(){
private int minutes;
private int seconds;
private Timer innerTimer = new Timer();
private TimerTask innerTask;
private boolean isActive;
public DownloadTimer(int minutes, int seconds) {
if (seconds > 60) {
int minToAdd = seconds / 60;
this.minutes = minutes;
this.minutes += minToAdd;
this.seconds = seconds % 60;
} else {
this.minutes = minutes;
this.seconds = seconds;
}
}
public void start() {
innerTask = new TimerTask() {
#Override
public void run() {
isActive = true;
System.out.println(getTime());
if (seconds == 0 && minutes > 0){
minutes -= 1;
seconds = 59;
} else if (seconds == 0 && minutes == 0){
isActive = false;
innerTimer.cancel();
innerTimer.purge();
System.out.println("DownloadTimer DONE");
} else {
seconds -= 1;
}
}
};
innerTimer.scheduleAtFixedRate(innerTask, 0, 1000);
}
}
And then, I'm creating the DownloadTimer object and starting the countdown from my Main (JavaFX) class:
/*
code omitted for better readability
*/
downloadTimer = new DownloadTimer(0, 5);
// label gets the .getTime() value, which returns a formatted String like "00:05", "00:04", etc.
lblTimer.setText( downloadTimer.getTime() );
// start the countdown
downloadTimer.start();
// create a new timer which checks if the downloadTimer is still counting
final Timer timer = new Timer();
TimerTask timerTask = new TimerTask(){
#Override
public void run(){
if (downloadTimer.getIsActive() == false){
timer.cancel();
timer.purge();
System.out.println("GUI timer DONE");
} else {
// if it's still running, then continuously update the label's text
lblTimer.setText( downloadTimer.getTime() );
// this is where I get the error described below
}
}
};
// repeat after 1000ms
timer.scheduleAtFixedRate(timerTask, 0, 1000);
The problem I'm encountering with this is that I can't set the label text with lblTimer.setText( downloadTimer.getTime() ); from the Main class, and the error I'm getting is TimerThread.run() line: not available [local variables unavailable] as seen here.
I've read about ScheduledThreadPoolExecutor and Java Timer vs ExecutorService, but I'm curious if this can be done using two separate Timers and TimerTasks. Any help and/or tips would be greatly appreciated.
I'm surprised you're not seeing an exception. To update a label from a separate thread, one needs to schedule an update to be run in the FX thread:
Platform.runLater(new Runnable() {
public void run() {
lblTimer.setText(downloadTimer.getTime());
}
});