我正在开发一个使用WebView
. 我想做一个ProgressBar
向用户显示加载页面的进度。我知道如何创建一个ProgressBar
,以及如何使用它,但我不知道如何获得WebView
/的进度WebEngine
。我如何获得进度以更新ProgressBar
?
user8188748
问问题
939 次
2 回答
0
你可以像下面的代码那样做:
使用后台线程java.util.Timer
或 Future 检索任务的方法仍然有效。但是JavaFX
有一个内置的 API 来做这样的事情,它是Service
和 Task 类(用于ScheduleService
重复任务)。
// 在 JavaFX 线程上。
final Service<Foo> service = new Service<Foo> {
@Override
protected Task<Foo> createTask() {
return new Task<Foo>() {
@Override
protected Foo call() throws Exception {
// On another thread.
[...]
if (isCancelled()) {
updateMessage("Cancelled");
return null;
}
updateProgress(currentProgress++, totalProgress);
updateMessage("Now doing stuff");
[...]
return result;
}
};
}
};
progressBar.progressProperty().bind(service.progressProperty());
service.setOnSucceeded(event -> {
// On the JavaFX thread.
progressBar.progressProperty().unbind();
final Foo foo = (Foo)event.getSource().getValue();
// Pass the result to the view.
[...]
});
service.setOnCancelled(event -> {
// On the JavaFX thread.
progressBar.progressProperty().unbind();
[...]
});
service.setOnFailed(event -> {
// On the JavaFX thread.
progressBar.progressProperty().unbind();
final Throwable ex = event.getSource().getException();
// Log and show.
[...]
});
service.start();
同一个 Service 可以重复使用多次(调用 cancel() 和 start() 或 restart()),而一个 Task 只能使用一次(Service 每次启动都会创建一个新的 Task)。
于 2019-02-16T08:22:49.913 回答
0
从以下文档WebEngine
:
加载总是发生在后台线程上。启动加载的方法在调度后台作业后立即返回。要跟踪进度和/或取消作业,请使用方法中
Worker
可用的实例getLoadWorker()
。
您所要做的就是观察progress
. Worker
这是一个小例子:
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.geometry.Insets;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ProgressBar;
import javafx.scene.control.Separator;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
WebView view = new WebView();
BorderPane root = new BorderPane(view, createTop(view), null, null, null);
primaryStage.setScene(new Scene(root, 1000, 600));
primaryStage.setTitle("WebView Example");
primaryStage.show();
}
private VBox createTop(WebView view) {
ProgressBar progBar = new ProgressBar();
progBar.progressProperty().bind(view.getEngine().getLoadWorker().progressProperty());
progBar.visibleProperty().bind(
Bindings.when(progBar.progressProperty().lessThan(0).or(progBar.progressProperty().isEqualTo(1)))
.then(false)
.otherwise(true)
);
progBar.managedProperty().bind(progBar.visibleProperty());
progBar.setMaxWidth(Double.MAX_VALUE);
VBox top = new VBox(5, createSearchBar(view), progBar, new Separator());
top.setAlignment(Pos.CENTER);
return top;
}
private HBox createSearchBar(WebView view) {
TextField urlField = new TextField("https://stackoverflow.com/");
view.getEngine().locationProperty().addListener(obs -> urlField.setText(view.getEngine().getLocation()));
Button loadBtn = new Button("Load");
loadBtn.setOnAction(event -> {
event.consume();
view.getEngine().load(urlField.getText());
});
loadBtn.disableProperty().bind(view.getEngine().getLoadWorker().runningProperty());
HBox searchBar = new HBox(5, urlField, new Separator(Orientation.VERTICAL), loadBtn);
searchBar.setPadding(new Insets(10, 10, 3, 10));
searchBar.setAlignment(Pos.CENTER);
HBox.setHgrow(urlField, Priority.ALWAYS);
return searchBar;
}
}
于 2019-02-16T08:55:01.453 回答