加载页面之间的JavaFX webview延迟

时间:2013-05-13 12:17:53

标签: java webview javafx

所以,我有一个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和整个线程,因此我不能将它放在加载链接之间。

有什么解决方案吗?在页面加载后加 > 开始加载下一页之前

此致

伊万

2 个答案:

答案 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)来处理暂停。