[英]How to make progress bar for web pages loading process in JavaFX?
我正在使用WebView
的JavaFX應用程序上工作。 我想制作一個ProgressBar
,向用戶顯示加載頁面的進度。 我知道如何創建一個ProgressBar
,以及如何使用它,但是我不知道如何獲取WebView
/ WebEngine
。 如何獲取進度以更新ProgressBar
?
您可以按照以下代碼進行操作:
使用后台線程檢索任務的方法, 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)。
從WebEngine
的文檔中:
加載始終發生在后台線程上。 計划后台作業后,立即返回啟動加載的方法。 要跟蹤進度和/或取消作業,請使用
getLoadWorker()
方法中可用的Worker
實例。
您要做的就是觀察Worker
的progress
屬性。 這是一個小例子:
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;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.