所以,我有一个webview,并希望一个接一个地加载2(或任何数字> 1)页面。但页面更改必须在上一页加载后不会立即发生,而是在一段时间后发生。例如:
public void load()
{
engine.load("link1");
//need to wait some time here
engine.load("link2");
//need to wait some time here
engine.load("link3");
}
我已尝试在页面加载时使线程休眠:
engine.getLoadWorker().stateProperty().addListener(new ChangeListener<Worker.State>() {
@Override
public void changed(ObservableValue observableValue, Worker.State o, Worker.State o2) {
if (o2.equals(Worker.State.SUCCEEDED)) {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
但它不起作用,因为engine.load()不会等到页面加载(因为我们有事件监听器)。另一个缺点是Thread.sleep()阻止了GUI和整个线程,因此我不能将它放在加载链接之间。
有什么解决方案吗?在页面加载后加
此致
伊万
答案 0 :(得分:2)
Thread.sleep(n);
它是绘制窗口的线程,这就是它将阻止GUI的原因。
您的问题的解决方案是在分离的线程中加载所有页面。 但如果你不在javaFX线程中,你就无法加载页面...... 解决方案是使用Platform.runLater()函数加载它。
因此,您必须将以下代码实现到一个独立的线程中,该线程可以在不阻塞GUI的情况下进行休眠。
Platform.runLater(new Runnable() {
@Override
public void run() {
webView.getEngine().load("http://www.my.url/");
}
});
答案 1 :(得分:1)
正如Engine在他的回答中指出的,Thread.sleep
阻止了UI更新线程,这不是你想要的。基本上,永远不要睡在UI线程上。
我建议将你的Thread.sleep调用替换为PauseTransition。
这样做的好处是JavaFX动画子系统为您处理线程,确保您的代码始终在适当的时间在UI线程上调用,因此您永远不必担心线程。 。 。在我看来,不需要担心线程总是好的。 。
engine.getLoadWorker().stateProperty().addListener(
new ChangeListener<Worker.State>() {
@Override
public void changed(
ObservableValue observableValue,
Worker.State oldState,
Worker.State state) {
if (state.equals(Worker.State.SUCCEEDED)) {
PauseTransition pause = new PauseTransition(Duration.seconds(3));
pause.setOnFinished(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
webView.getEngine().load("http://www.mynext.url/");
}
});
pause.play();
}
}
}
);
你可能需要一些额外的逻辑来从诸如工作者状态为FAILED之类的东西中恢复,这样你的幻灯片效果就不会在第一次出现连接错误时停止工作。
如果您不确定自己是否在UI线程上,请添加一个调试语句,以便您考虑睡眠:
System.out.println(Thread.currentThread().getName());
如果名称为“FX Application Thread”,则应使用其他机制(如动画框架或Task)来处理暂停。