multithreading - JavaFX Wait for Page to Load Before Continuing -
i have method sets new web page webview's webengine needs wait until page has finished loading continue in current method.
essentially want:
mymethod() { navigatetonewurl(); waitforpagetoload(); // part struggling dosomethingelse(); }
i have tried using changelistener() execute after method has finished executing. have googled many terms lead more frustration, "java non-blocking wait boolean". made far starting new threads (to prevent application gui locking up) , using countdowntimer ( opposed thread.join() ). following code umpteenth attempt @ getting whati want.
public static boolean pageloaded; public volatile static countdownlatch latch; private static void testmethod() { // set countdownlatch latch = new countdownlatch(1); // set page loaded flag pageloaded = false; // navigate new window mywebview.getengine().load("https://www.google.com/"); // call method, starts thread, checks if page has loaded waitforpageloaded(); // wait countdownlatch, latch try { latch.await(); } catch (interruptedexception e) { /* todo auto-generated catch block */ e.printstacktrace(); } // write result console system.out.println("[pageloaded] " + pageloaded); } private static void waitforpageloaded() { thread thread = new thread() { public void run() { // 120 iterations * 250 ms = 30 seconds (int = 0; < 120; i++) { // check if page has loaded if (pageloaded == true) { break; } else { system.out.println("waited " + (i*250) + " milliseconds, far..."); try { thread.sleep(250); } catch (interruptedexception e) { /* todo auto-generated catch block */ e.printstacktrace(); } } } // tell calling method move on life latch.countdown(); } } }
and in .java file (class) have:
// webengine , set listener state change webengine webengine = webview.getengine(); webengine.getloadworker().stateproperty().addlistener ( new changelistener<state>() { public void changed(@suppresswarnings("rawtypes") observablevalue ov, state oldstate, state newstate) { if (newstate == state.succeeded) { // set page loaded flag otherclassname.pageloaded = true; } } } );
like ui frameworks, javafx based on event-driven model. behind scenes there loop runs (in fx application thread) processes events. should not deal directly loop.
you trying solve problem recreating loop , waiting condition, instead of registering handlers respond appropriate events. instead of waiting in thread (which thread? there's no obvious way this) page load, need respond each page completing loading , perform next step in test process. can registering listener on web engine's stateproperty
.
so structure should like
public class myapp extends application { private webview webview ; private webengine engine ; // variables representing current state of testing process... @override public void start(stage primarystage) { webview = new webview(); engine = webview.getengine(); engine.getloadworker().stateproperty().addlistener((obs, oldstate, newstate) -> { if (newstate == worker.state.succeeded) { // new page has loaded, process: testmethod(); } }); // set ui etc... engine.load(...); // load first page } private void testmethod() { // check current state, next appropriate thing, update variables... } }
this structure achieves trying - testmethod()
invoked repeatedly, when each page has finished loading - "waiting" managed framework.
Comments
Post a Comment