javafx - java thread immediately update UI -


i have javafx application visualizes compuational geometry algorithms. execution of algorithm happens in thread, lets call maincomputingthread. algorithm can update ui @ time adding/removing/modifying shapes. code like:

//do computaions (1) updateui(); //do more calculations (2) 

what want know in updateui method update ui , prevent calling thread running further (marked (2)) until ui update done.

i thought boolean guards. code like:

updateui(){    boolean guard = false;    platform.runlater(new runnable()    {       run(){         //do actual update         guard = true;       }    });    while(guard==false); } 

i hope idea of mean. i'm curious if there's better solution problem...

simple approach: block background thread until update complete:

you need update ui on fx application thread. typically passing plain runnable platform.runlater(...).

if want wait ui update complete before proceeding, instead create futuretask , pass platform.runlater(...). can call get() on futuretask, block until task complete:

private void updateui() throws interruptedexception {      // actual work update ui:     futuretask<void> updateuitask = new futuretask(() -> {          // code update ui...      }, /* return value task: */ null);      // submit execution on fx application thread:     platform.runlater(updateuitask);      // block until work complete:     updateuitask.get(); } 

this lets futuretask handle tricky work of waiting , notifying: better use higher-level api kind of work when can.

if like, can refactor utility method, dainesch's answer:

public class fxutils {      public static void runandwait(runnable run) throws interruptedexception {         futuretask<void> task = new futuretask<>(run, null);         platform.runlater(task);         task.get();     } } 

alternative approach: ensure no more 1 update consumed during frame rendering, blocking background thread if update pending

here different approach. create blockingqueue capacity of 1 hold runnables update ui. background thread, submit runnables blocking queue: since blocking queue can hold @ 1 element, block if 1 pending.

to execute updates in queue (and remove them, more can added), use animationtimer. looks like:

private final blockingqueue<runnable> updatequeue = new arrayblockingqueue<>(1); 

background thread code:

// computations...  // block while there other updates pending:     updatequeue.put(() -> {     // code update ui     // note not need explicitly executed on fx application     // thread (no platform.runlater()). animation timer take care of });  // more computations 

create timer consume updates:

animationtimer updatetimer = new animationtimer() {      @override     public void handle(long timestamp) {         runnable update = updatequeue.poll();         if (update != null) {             // note on fx application thread:             update.run();         }     } };  updatetimer.start(); 

this ensures no more 1 update ever scheduled @ time, background thread blocking until pending updates consumed. animation timer checks (without blocking) pending updates on each frame rendering, ensuring every update executed. nice thing approach can increase size of blocking queue, keeping buffer of pending updates, while still ensuring no more 1 update consumed during single frame rendering. might useful if there occasional computations take longer others; gives these computations chance calculated while others waiting executed.


Comments

Popular posts from this blog

angularjs - ADAL JS Angular- WebAPI add a new role claim to the token -

php - CakePHP HttpSockets send array of paramms -

node.js - Using Node without global install -