layout.setBackgroundColor(Color.GREEN);
try {
Thread.sleep(1250);
} catch (InterruptedException e) {
e.printStackTrace();
}
layout.setBackgroundColor(Color.BLUE);
I want to change the BackgroundColor of my Layout to green at first and after waiting for 1.25 sec it should turn blue.
The BackgroundColor changes to blue after 1.25 sec but does not turn Green before. How can I fix this?
You are putting main thread (UI thread) on sleep which is causing the issue.
Try this
layout.setBackgroundColor(Color.GREEN);
layout.postDelayed(new Runnable() {
#Override
public void run() {
layout.setBackgroundColor(Color.BLUE);
}
}, 1250);
Make sure layout is declared as final.
You have just changed your background color twice above. So it's considered your last BLUE color only.
you have to do something like this.
layout.setBackgroundColor(Color.GREEN);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
layout.setBackgroundColor(Color.BLUE);
}
}, 1250);
Try Handler like this:
layout.setBackgroundColor(Color.GREEN);
Handler h=new Handler();
h.postDelayed(new Runnable() {
#Override
public void run() {
layout.setBackgroundColor(Color.BLUE);
}
},1250);
Never, do Thread.sleep() on a UI thread.
That is what is causing the problem initially.
you could use this to sleep eg. background thread.
This Handler solution has two advantages:
(1) avoids system overhead of 2nd thread,
(2) runs on UI thread, so can make UI changes without causing an exception.
Related
Lets say I have a ImageView that executes at a click of a Button:
final ImageView ball = new ImageView(v.getContext());
ball.setImageResource(R.drawable.ball_1);
gameConstraintLayout.addView(ball);
When I click that button, it first off makes the ball appears , creates and runs another thread that tell itself to sleep 1000 milliseconds sleep(long millis) then removes the ball by calling ConstrainLayout.removeView(view)
Here is the full minimal code:
final ImageView ball = new ImageView(v.getContext());
currentBullet.setImageResource(R.drawable.ball_1);
gameConstraintLayout.addView(ball);
ballAppears.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(final View v) {
final ImageView ball = new ImageView(v.getContext());
currentBullet.setImageResource(R.drawable.ball_1);
gameConstraintLayout.addView(ball);
Thread thread = new Thread() {
#Override
public void run() {
try {
sleep(1000);
contraintLayout.removeView(ball)
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
});
Problem is;
The ball appears on screen, the other thread successfully sleeps for 1000 milliseconds, but, It crashes when It tries to remove the ball from the constraint layout in the other thread.
Logcat:
android.view.ViewRootImpl$CalledFromWrongThreadException: **Only the original thread that created a view hierarchy can touch its views**.
at android.support.constraint.ConstraintLayout.removeView(ConstraintLayout.java:645)
at com.mobilegames.***.******.GameActivity$1$1.run(GameActivity.java:51)
The code that causes the problem is:
gameConstraintLayout.removeView(ball_1);
AS it seems,I cant access the Constraint layout from the other thread but, I can still change the X and the Y of the ball.
I even tried running that piece of code in the UI theard runOnUIThread(...), but to no avail.
Here is the runONUIThread code:
shootTank.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(final View v) {
final ImageView currentBullet = new ImageView(v.getContext());
currentBullet.setImageResource(R.drawable.bullet_model1);
gameConstraintLayout.addView(currentBullet);
Thread thread = new Thread() {
#Override
public void run() {
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
runOnUiThread(new Runnable() {
public void run() {
gameConstraintLayout.removeView(currentBullet);
}
});
}
};
thread.start();
}
});
Any possible solutions? Keep in mind that I change the X and Y's of the ball after every second.
AND YES, I did check other Questions. The answer in those ones said to simply run it on the UI thread, but of course I already tried that. If i run the sleep(long millis) into the UI thread, obliviously, the whole app would be irresponsible.
(This is not the full app; it was broken down into a much more simpler and understandable Question. I end up changing the ball's X and Y in the separate thread, but that inst what is causing the problem. Please tell me in comments if editing is necessary)
Sorry for small grammar mistakes
Use handler to perform your actions with some delay. For example:
Handler h = new Handler();
h.postDelayed(new Runnable() {
public void run() {
gameConstraintLayout.removeView(currentBullet);
}
}, 1000); // here 1000 is delay in milliseconds (1sec)
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'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.
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
In my method, I want to call another method that will run 1 second later. This is what I have.
final Timer timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
MyMethod();
Log.w("General", "This has been called one second later");
timer.cancel();
}
}, 1000);
Is this how it's supposed to be done?
Are there other ways to do it since I'm on Android?
Can it be repeated without any problems?
There are several alternatives. But here is Android specific one.
If you thread is using Looper (and Normally all Activity's, BroadcastRecevier's and Service's methods onCreate, onReceive, onDestroy, etc. are called from such a thread), then you can use Handler. Here is an example:
Handler handler = new Handler();
handler.postDelayed(new Runnable()
{
#Override
public void run()
{
myMethod();
}
}, 1000);
Note that you do not have to cancel anything here. This will be run only once on the same thread your Handler was created.
Instead of a Timer, I'd recommend using a ScheduledExecutorService
final ScheduledExecutorService exec = Executors.newScheduledThreadPool(1);
exec.schedule(new Runnable(){
#Override
public void run(){
MyMethod();
}
}, 1, TimeUnit.SECONDS);
If you are not in UI thread, consider adding a very simple:
try
{
Thread.sleep( 1000 );
}//try
catch( Exception ex)
{ ex.printStackTrace(); }//catch
//call your method
ScheduledExecutorService or AsyncTask for UI related.
Note that if you are to update UI, that code should be posted to UI thread. as in Processes and Threads Guide
final Bitmap bitmap = loadImageFromNetwork("http://example.com/image.png");
mImageView.post(new Runnable() {
public void run() {
mImageView.setImageBitmap(bitmap);
}
});
There is also nice postDelayed method in View
mImageView.postDelayed(new Runnable(){
#Override
public void run() {
mImageView.setImageResource(R.drawable.ic_inactive);
}
}, 1000);
that will update UI after 1 sec.