gpt4 book ai didi

multithreading - JavaFX等待页面加载,然后继续

转载 作者:行者123 更新时间:2023-12-03 13:17:22 24 4
gpt4 key购买 nike

我有一个为WebView的WebEngine设置新网页的方法,该方法需要等到该页面完成加载后才能继续使用当前方法。

本质上我想要:

MyMethod()
{
navigateToNewUrl();
waitForPageToLoad(); // This is the part I am struggling with
doSomethingElse();
}

我尝试使用ChangeListener(),但是它只会在我的方法完成执行后才执行。我用谷歌搜索了许多导致更多挫败感的术语,例如“java non-blocking wait boolean”。最终,我尽可能地启动了新线程(以防止Application GUI锁定)并使用CountDownTimer(与Thread.join()相对)。下面的代码是我无数次尝试达到我想要的。
public static Boolean pageLoaded;
public volatile static CountDownLatch latch;

private static void TestMethod()
{
// Set the CountDownLatch
latch = new CountDownLatch(1);

// Set the page loaded flag
pageLoaded = false;

// Navigate to new window
myWebView.getEngine().load("https://www.google.com/");

// Call a method, that starts a thread, that checks if the page has loaded
WaitForPageLoaded();

// Wait for the CountDownLatch, latch
try { latch.await(); } catch (InterruptedException e) { /* TODO Auto-generated catch block */ e.printStackTrace(); }

// Write result to console
System.out.println("[pageLoaded] " + pageLoaded);
}

private static void WaitForPageLoaded()
{
Thread thread = new Thread()
{
public void run()
{
// 120 iterations * 250 ms = 30 seconds
for (int i = 0; i < 120; i++)
{
// Check if page has loaded
if (pageLoaded == true)
{
break;
}
else
{
System.out.println("Waited " + (i*250) + " milliseconds, so far...");
try { Thread.sleep(250); }
catch (InterruptedException e) { /* TODO Auto-generated catch block */ e.printStackTrace(); }
}
}

// Tell the calling method to move on with life
latch.countDown();
}
}
}

在另一个.java文件(类)中,我有:
        // Get the WebEngine and set a listener for a 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 the page loaded flag
OtherClassName.pageLoaded = true;
}
}
}
);

最佳答案

与几乎所有UI框架一样,JavaFX基于事件驱动模型。幕后有一个循环运行(在FX Application Thread中),用于处理事件。您不应该直接处理此循环。

您正在尝试通过重新创建此循环并等待条件来解决此问题,而不是注册响应适当事件的处理程序。无需等待页面加载线程(哪个线程?没有明显的方法),您只需响应每个页面以完成加载并执行测试过程的下一步即可。您可以通过在Web引擎的stateProperty上注册一个监听器来做到这一点。

所以你的结构应该看起来像

public class MyApp extends Application {

private WebView webView ;
private WebEngine engine ;

// variables representing the current state of your 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 up UI etc...

engine.load(...); // load first page

}

private void testMethod() {
// check current state, do next appropriate thing, update variables...
}

}

这种结构完全可以实现您想要做的事情-重复调用 testMethod(),但仅在每个页面完成加载后才调用-但框架会为您管理“等待”。

关于multithreading - JavaFX等待页面加载,然后继续,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30178238/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com