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.
Related
I'm currently programming a mini game in java swing. I've got the GUI set up, and the game involves a sequence of numbers flashing up on screen and then disappearing - the user must then input the numbers again in the sequence they appeared.
When the numbers are initially displayed, I want them to display for 1-2 seconds, and then disappear, and have another number for 1-2 seconds etc.
However, I'm having issues with delaying the program whilst the number displays. I can't use Thread.sleep as it pauses the whole program with the hiding of previous numbers etc. It just doesn't work. I've tried every other suggestion I've come across, none of which have worked yet.
Anyone got anymore tips?
int delay = 5000; // delay in milliseconds
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) { //...Perform a task... } };
Timer timer = new Timer(delay, taskPerformer);
timer.setRepeats(false);
timer.start(); // timer starts - after delay time your task gets executed
Source
You can use Thread.sleep()
The problem you having is probably because you are trying to update the UI from Swing's event dispatching thread. This is a thread that is reserved for Swing components and you should do exactly nothing in it except quick updates to the UI.
public void prog() {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
label.setText("1");
}
}
try {
Thread.sleep(5000);
} catch(Exception e) { }
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
label.setText("2");
}
}
}
public static void main(String[] args) {
label = new JLabel("0");
prog();
}
JLabel label
The UI should remain responsive because of it's component interactions should be implemented in ActionListener's. But if you want to perform other work while waiting, or if the feature is contained in an ActionListener's actionPerfomed() method, you can kick off a new thread to sleep 5 seconds then update the UI. You could also perform some calculations that take 5 seconds to compute instead of sleeping without blocking the UI. The code would be:
(new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(5000);
} catch (Exception e) { }
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
label.setText("2");
}
}
}
}).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 am trying to run android.animation.ValueAnimator from a separate thread from the UI thread. As I understand it, ValueAnimator can only be ran from the UI thread. Is there a proper way to start it from another thread to run on the UIThread?
I wrapped the ValueAnimator in an other class which holds a switch for the UI thread to periodically check.
private ArrayList<Animation> animators;
public void onResume(){
while(true)
{
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
checkAnimations();
}
}
public void checkAnimations()
{
for(Animation va: animators)
{
if(va.animationHasStarted())
va.actuallyStartTheAnimation();
}
}
public void RegisterAnimation(Animation valueAnimator)
{
animators.add(valueAnimator);
}
The infinite loop causes the UI to stall. Do you know of a better implementation/design pattern.
I'm using a button to start a background service in my app. This is the code I'm using:
#Override
public void actionPerformed(ActionEvent action) {
if (action.getActionCommand().equals("Start")) {
while (true) {
new Thread(new Runnable() {
public void run() {
System.out.println("Started");
}
}).start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
This does update the service every second, which it what I want. Problem is it freezes the rest of the application. How do I implement it so that that doesn't happen?
The following is likely to cause your application to pause:
while (true) {
...
}
Try removing those lines.
Edit: as per comment, to make the newly-launched thread fire every second, move the sleep and while loop inside the run() method:
if (action.getActionCommand().equals("Start")) {
new Thread(new Runnable() {
public void run() {
while (true) {
System.out.println("Started"); }
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
You're calling this method in the Thread that updates the GUI, and this you're pausing the GUI refresh. Spawn a new thread and execute that there.
an infinite loop ??
while (true) {.....}
how you supposed to get out of here -
add an print statement inside loop and you will come to know that you have been stuck here after button click
Ok I got it. Here's what I should have done:
#Override
public void actionPerformed(ActionEvent action) {
if (action.getActionCommand().equals("Start")) {
new Thread(new Runnable() {
public void run() {
while (true) {
System.out.println("Started");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
}
I would like to get a recurring call back to invalidate a view. I am sure there is a neat way to do this. I am currently doing this and would like a neater / better solution if possible?
new Thread()
{
#Override
public void run()
{
while (!Thread.currentThread().isInterrupted())
{
handler.post(new Runnable()
{
public void run()
{
BannerButton.this.invalidate();
}
});
try
{
Thread.sleep(50); // yields 20 fps
} catch (InterruptedException e)
{
Thread.currentThread().interrupt();
}
}
}
}.start();
For a single shot timer on the UI thread, I do this: (But I cant find a way to do this with repeats)
(new Handler()).postDelayed(new Runnable()
{
#Override
public void run()
{
// Do stuff
}
}, SPLASH_SHOW_TIME);
Timer looked good, but it calls on a background thread.
Thanks.
Your second try using Handler is already correct. Just store the Handler and the Runnable in a field, and then inside the run() method (possibly at the end), call again
handler.postDelayed(runnable, 1000);
Look at the View.postInvalidate() method. This is different from invalidate() as you can do it from any Thread you want. It just posts an invalidate() message in the UI thread Looper
Concerning your second question simply post with some delay the same Runnable at the end of the Runnable in your Handler