Update GUI without hang - java

i have action list which is a ArrayList. Object Action contains 3 parameters(button, action, time_it_takes). So what i have to is get a action form ArrayList perform it and wait for a while and then next action and so on. I have tried but nothing is updating in view it just hang for sometime and nothing updated. I have tried runOnUiThread but it also gives me error. Actually, i think i have weak multithreading concepts. Here is what i am trying...
public void replay()
{
ArrayList<Action> actions = gui.getActionList();
for(i =0; i<actions.size(); i++)
{
gui.Replay(actions.get(i));
try
{
Thread.sleep(actions.get(i).getTime()); // delay for the next task
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Help Please

From your comments you are calling replay() from your activity which runs on the ui thread
You are calling sleep on the ui thread which blocks the ui thread. You should not block the ui thread. Do not call Thread.sleep(2000) in the ui thread.
http://developer.android.com/training/articles/perf-anr.html
You can use a Handler if you wish you execute something every few seconds.
Handler m_handler;
Runnable m_handlerTask ;
m_handler = new Handler();
m_handlerTask = new Runnable()
{
#Override
public void run() {
// do something every 1 second
m_handler.postDelayed(m_handlerTask, 1000);
}
};
m_handlerTask.run();
To cancel the run
m_handler.removeCallbacks(m_handlerTask);

Related

wait for GUI created by event dispatch thread

I've got a class that creates and runs a thread, which creates a GUI.
I want the initial class to remain suspended until the GUI is closed (OK button for example)
I tried thread.join(); but since the GUI is created on the event dispatch thread this does not seem to work, and the class continues as the GUI pops up.
private void CreateAndRunThread(){
GUIMaker GM= new GUIMaker(data);
GM.run();
try {
TFM.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
MessageDialog.showDialog("GM Done");
}
thread's GUI creation:
#Override
public void run() {
//Schedule a job for the event dispatch thread:
//creating and showing this application's GUI.
SwingUtilities.invokeLater(new Runnable() {
public void run() {
//Turn off metal's use of bold fonts
UIManager.put("swing.boldMetal", Boolean.FALSE);
CreateAndShowGUI(frame); //adds frame, packs and sets visible
}
});
}
Use CountDownLatch:
CountDownLatch latch = new CountDownLatch(1);
Call the following in the inital class to block:
latch.await();
Call the following when the GUI is closed:
latch.countDown();
Also it seems that you are not starting thread properly. You need to call GM.start() method instead of GM.run().

Updating imageViews in onTouchEvent in realtime

In my onTouchEvent method (in a class that extends Activity), I have some imageViews that change one by one, which is done by waiting a little before executing the next change.
//in the onTouchEvent method
//ivList is an arrayList of imageViews
ivList.get(0).setImageResource(R.drawable.drawable1);
synchronized (this) {
try {
wait(500);
} catch (InterruptedException e) {
}
}
ivList.get(1).setImageResource(R.drawable.drawable2);
However, when this is executed, the changes only take place once onTouchEvent is concluded, so the result is a minor delay and then both imageViews change at once, as opposed to one imageView changing, a minor delay, and then the second one changes. Can someone explain how to fix this?
The problem is you should not use wait() because it will block the main thread
ivList.get(0).setImageResource(R.drawable.drawable1); // this is doing in main thread
synchronized (this) {
try {
wait(500); // this blocks the main thread
} catch (InterruptedException e) {
}
}
ivList.get(1).setImageResource(R.drawable.drawable2); // this is also doing in main thread
try following
Runnable r = new Runnable() {
#Override
public void run() {
ivList.get(1).setImageResource(R.drawable.drawable2);
}
};
ivList.get(0).setImageResource(R.drawable.drawable1);
// no synchronized is needed
new Handler().postDelayed(r,500); // call to change the image after 500s
of cause your Runnable and Handler can create else where so that you do not need to create them every time the onTouchEvent is trigeered
okay , if you are going to make it work for 10 images.
// these are local variables
//create a contant int array for the 10 images
int[] imgs = {R.drawable.drawable1 , R.drawable.drawable2 ,....,R.drawable.drawable10};
int count = 0; // counting which image should show
// local variable ends
// initialize
Handler handler = new Handler();
Runnable r = new Runnable() {
#Override
public void run() {
if (count < 9){
count++;
ivList.get(count).setImageResource(imgs[count]);
handler().postDelayed(r,500);
}
}
};
// in your touch event
ivList.get(0).setImageResource(R.drawable.drawable1);
// no synchronized is needed
handler().postDelayed(r,500); // call to change the image after 500s

Why is my Thread making my JavaFX Application lag?

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.

Frozen interface even with new thread

Hi i'd like to do a task out of the EDT because i don't want to froze my interface each time i click on a button :
The long-time task is the function paintComponent of fBPC then i have to create new thread for fBPC.repaint(). But even with this new thread my interface still freeze ( because i'd like to click on my button while the task is done in background ), how can i do? Maybe should i create the thread in an other part ?
new Thread(new Runnable(){
#Override
public void run() {
// TODO Auto-generated method stub
fBPC.repaint();
System.out.println("toto");
if (SwingUtilities.isEventDispatchThread()){
System.out.println("titi");
}
}
}).start();

Proper way to get a Recurring Callback on the UI thread

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

Categories

Resources