I am trying to create a circuit timer using the countdown timer. When the thread is sleeping I want the text to display "Change!" and this to display for 5 seconds before the countdown timer starts again. I am unsure how to get this working. I know the thread is sleeping and so wont display the "Change!" until after it has woke up again after the 5 seconds. But I cannot understand how to get it working the way I wish it to. Can anyone help me solve this issue?
public void onFinish()
{
// Text to be displayed when thread is sleeping
time.setText("Change!");
try
{
Thread.sleep(5000);
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
if (numberOfCircuits != 15)
{
start();
numberOfCircuits++;
}
else
{
countDownTimer.cancel();
}
}
Instead of making the main thread sleep(you are likely to get an ANR dialog), you can use a Timer which can notify you of your 5sec lapse and you can schedule your CountDownTimer again.
public void onFinish()
{
// Text to be displayed when thread is sleeping
time.setText("Change!");
new Timer("Sleeper").schedule(new TimerTask() {
#Override
public void run() {
if (numberOfCircuits != 15)
{
start();
numberOfCircuits++;
}
else
{
countDownTimer.cancel();
}
}
}, 5000); // 5 sec delay
}
Related
(V1) I have a countdown object that deals with displaying a countdown on the JFrame by using a timer. Once the countdown goes to 0, I want the timer to stop and the game to start. However, I realized that even when my countdown isn't finished, my startGame() method is being run, and I cannot find a solution to make it so that the startGame() method only runs after the timer is stopped. So, my question is: is there anyway to make sure the startGame() only runs AFTER the countdown hits zero?
(V2) I tried using countdown.getTimer.isRunning()in the init() method to check whether or not the timer is running (if not then call startGame()) but that didn't seem to work. I'm guessing this is because at the time the if block is called, the timer is still running, so that's why startGame() isn't called... Is this why?
A little explanation of the code: the startCountdown() method tries to display the next image while hiding the last, so I have the catch for the first case where it tries to hide a non-existant image at an index that is out of bounds. Each time the timer ticks, I decrement sec by 1 until it is 0, and then the timer stops.
V1
public void init() {
countdown.startCountdown();
countdown.getTimer().start();
startGame();
}
public void startCountdown() {
timer = new Timer(1000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
try {
if (sec == 0) {
countdownIcons.get(0).setVisible(false);
timer.stop();
}
countdownIcons.get(sec - 1).setVisible(true);
countdownIcons.get(sec).setVisible(false);
} catch (IndexOutOfBoundsException exception) {
if (sec == 0) {
timer.stop();
}
}
sec--;
System.out.println(sec);
}
});
}
V2
public void init() {
countdown.startCountdown();
countdown.getTimer().start();
if (!countdown.getTimer().isRunning()) {
startGame();
}
}
The problem is that the Timer method runs on a separate thread, different from your main thread.
The way I see it there are two possible solutions:
call your startGame() method inside startCountdown(), not inside init();
the second solution would be to pause your main thread and wait for startCountdown() to finish, something like this should work:
public void init() {
countdown.startCountdown();
countdown.getTimer().start();
// pause main thread until timer is notified
synchronized(timer){
timer.wait()
startGame();
}
}
public void startCountdown() {
timer = new Timer(1000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
try {
if (sec == 0) {
countdownIcons.get(0).setVisible(false);
timer.stop();
// notify your current thread that it can resume execution
synchronized(timer){
timer.notify();
}
}
countdownIcons.get(sec - 1).setVisible(true);
countdownIcons.get(sec).setVisible(false);
// try not to catch this runtime exception and fix what causes IndexOutOfBoundsException
} catch (IndexOutOfBoundsException exception) {
if (sec == 0) {
timer.stop();
}
}
sec--;
System.out.println(sec);
}
});
}
I am having difficulty with a timer for Minesweeper. timeLabel is a Jlabel for the allowed time remaining in the level, and time is the allowed time (in seconds). The problem is, whenever I restart the game, it will speed up the timer. Does calling the method again when I restart cause this? And what can I do to fix this?
public void addTimer(int t){
time = t;
countDown = new Thread(){
public void run(){
while(time >= 0){
timeLabel.setText(time + "");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
}
time -= 1;
}
}
};
countDown.start();
}
I want to display a text before executing the function mediaPlayer(). During the execution of the mediaplayer, I sleep the thread. That's ok because nothing needs to happen then (then just need to listen).
However, the last text: "Listen to...", is not being displayed (except with a few seconds delay). It there a way to flush the jFrame first before the thread goes to sleep?
expText.setText("Listen to the song and give a rating when it finishes.");
startButton.setEnabled(false);
//play sound
try {
mediaPlayer();
//wait for the duration of the stimuli
Thread.sleep(stimDuration);
...
The setText won't display until the EDT renders another frame, which it can't do because it's busy sleeping for stimDuration amount of time.
Try to play the sound on a separate thread, play the sound on some other thread, detect when the sound stops, and then do another action on the EDT where you change expText back to the original text that you had.
The following combined use of Threads and Swing Timer solved the problem.
Thread t2 = new Thread(new Runnable() {
public void run() {
try {
startButton.setEnabled(false);
startButton.setVisible(false);
buttonsPanel.setEnabled(false);
buttonsPanel.setVisible(false);
expText.setText("Listen to the song and give a rating when it finishes.");
} catch (Exception e1) {
e1.printStackTrace();
}
}
});
t2.start();
Thread t1 = new Thread(new Runnable() {
public void run() {
// code goes here.
try {
mediaPlayer();
// Thread.sleep(5000);
} catch (Exception e1) {
e1.printStackTrace();
}
}
});
t1.start();
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
//...Perform a task...
resultButtonGroup.clearSelection();
startButton.setEnabled(true);
startButton.setVisible(true);
buttonsPanel.setVisible(true);
}
};
Timer timer = new Timer(stimDuration ,taskPerformer);
timer.setRepeats(false);
timer.start();
I'm trying to make an JavaFX application that tracks the movement of my mouse for this im using this code in the controller class:
new Thread(new Runnable() {
#Override public void run() {
while (Main.running) {
Platform.runLater(new Runnable() {
#Override
public void run() {
try {
label.setText(MouseInfo.getPointerInfo().getLocation().toString());
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
}
}).start();
But it couses my application to lag big time.
How should i fix this lag problem?
Thanks i fixed it:
new Thread(new Runnable() {
#Override public void run() {
while (Main.running) {
Platform.runLater(new Runnable() {
#Override
public void run() {
label.setText(MouseInfo.getPointerInfo().getLocation().toString());
}
});
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
What you doing is letting Javafx Application thread Thread.sleep(1000); <-wait
Any long term action you shoud put OUT of JFX-AT. And only update your ui components on it.
new Thread(()->{
while(Main.running){
Platform.runLater(()->{
//updateui component
//this is updating on FXAT
});
Thread.sleep(time)//This way you dont let JFXAT wait
}
}).start();
//Not sure if formatted and curly braces correctly.Bud you hopefully understand.Make sure you know which thread you let wait.Otherwise you wont be able to recieve events from paused jfxat.
You should put your Thread.sleep() call in your while loop and not in your Runnable, otherwise the loop keeps posting a lot of runLater tasks and those tasks stops the event thread for 1000ms after updating your mouse position
You call Thread.sleep(long) inside a Runnable that will be executed on the UI thread. If the thread is sleeping, it can't do anything else but sleep there. If you want your label to update every 1000 milliseconds, you can use the java.util.Timer class to make that happen.
On button click I am calling following function.
private void badButtonHandler() {
Camera.Parameters params = mCamera.getParameters();
params.setColorEffect(Camera.Parameters.EFFECT_NEGATIVE);
mCamera.setParameters(params);
if(thread != null){
thread = null;
}
thread = new Thread()
{
#Override
public void run() {
try {
while(true) {
sleep(5000);
Camera.Parameters params = mCamera.getParameters();
params.setColorEffect(Camera.Parameters.EFFECT_NONE);
mCamera.setParameters(params);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
thread.start();
}
This function is intended to change the Color Effect of Camera after 5 seconds of button click. When pressing the related button for the first time it behaves as expected. But additional calls to this function do not behave as expected. I.e., the second time it waits for 2 seconds, after which it decreases to lower values with every click.
You should not be relying on sleep() as an accurate timer. It won't automatically wake up at the designated time and become the currently active thread, because of the simple fact that all threads are at the mercy of the thread scheduler. Which undoubtedly will vary from OS to OS based on the given JVM.
I have always relied on custom timer functions for these types of scenarios. So, for example:
myTimer(System.nanoTime());
public static void myTimer(long startTime) {
while (startTime + 5000000000 > System.nanoTime()) { //Wait for 5 seconds
try {
Thread.sleep(50); //Sleep at ~50 millisecond intervals
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
You won't need to create an entirely new thread as you have done in your example, since Thread.sleep() will put the current thread to sleep. Also, using a while(true) loop is just poor programming practice.
Using nanoTime() is preferred since it is the most precise system timer available in Java.
See this documentation for additional info on the unreliability of the sleep() function.
try this
Thread timer = new Thread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
//Your desired work
}
}
});
timer.start();