ajax - How can a JSF/ICEfaces component's parameters be updated immediately? -
i have icefaces web app contains component property linked backing bean variable. in theory, variable value programmatically modified, , component sees change , updates appearance/properties accordingly.
however, seems change in variable isn't "noticed" component until end of jsf cycle (which, basic understanding, render response phase).
the problem is, have long file-copy operation perform, , the inputtext component show periodic status update. however, since component updated @ render response phase, doesn't show any output until java methods have finished executing, , shows changes accumulated @ once.
i have tried using facescontext.getcurrentinstance().renderresponse() , other functions, such pushrenderer.render(string id) force xmlhttprequest initialize early, no matter what, appearance of component not change until java code finishes executing.
one possible solution comes mind have invisible button somewhere automatically "pressed" bean when step 1 of long operation completes, , clicking it, calls step 2, , on , forth. seems work, don't want spend time hacking such inelegant solution when hope there more elegant solution built jsf/icefaces.
am missing something, or resorting ugly hacks way achieve desired behavior?
multithreading missing link, in conjunction pushrenderer , portablerenderer (see http://wiki.icesoft.org/display/ice/ajax+push+-+apis).
i have 3 threads in backing bean- 1 executing long operation, 1 polling status, , 1 "main" thread spawning new threads , returning ui control client browser.
once main thread kicks off both execution , polling threads, terminates , completes original http request. portablerenderer declared portablerender portablerenderer; , in init() method (called class constructor) contains:
pushrenderer.addcurrentsession("fullformgroup"); portablerenderer = pushrenderer.getportablerenderer(); for threading part, used implements runnable on class, , handling multiple threads in single class, followed stackoverflow post: how deal multiple threads in 1 class?
here's source code. can't reveal explicit source code i've used, boiled-down version doesn't reveal confidential information. haven't tested it, , wrote in gedit might have syntax error or two, should @ least started in right direction.
public void init() { // method called constructor. // doesn't matter define portablerenderer, long it's before it's used. pushrenderer.addcurrentsession("fullformgroup"); portablerenderer = pushrenderer.getportablerenderer(); } public void somebeanmethod(actionevent evt) { // backing bean method called ui event (e.g. clicking button) // since part of jsf/http request, cannot call portablerenderer.render copyexecuting = true; // create status thread , start thread statusthread = new thread(new runnable() { public void run() { try { // message , progress both linked components, change on portablerenderer.render("fullformgroup") call message = "copying..."; // initiates render. note cannot called thread part of http request portablerenderer.render("fullformgroup"); { progress = getprogress(); portablerenderer.render("fullformgroup"); // render updated progress thread.sleep(5000); // sleep while until it's time poll again } while (copyexecuting); progress = getprogress(); message = "finished!"; portablerenderer.render("fullformgroup"); // push render 1 last time } catch (interruptedexception e) { system.out.println("child interrupted."); } }); statusthread.start(); // create thread initiates script , triggers termination of statusthread thread copythread = new thread(new runnable() { public void run() { file somebigfile = new file("/tmp/foobar/large_file.tar.gz"); scriptresult = copyfile(somebigfile); // take long time, why spawn new thread copyexecuting = false; // caue statusthread's do..while loop terminate } }); copythread.start(); }
Comments
Post a Comment