Как сделать индикатор выполнения процесса загрузки веб-страниц в JavaFX? - PullRequest
0 голосов
/ 16 февраля 2019

Я работаю над приложением JavaFX, которое использует WebView.Я хотел бы сделать ProgressBar, который показывает пользователю процесс загрузки страницы.Я знаю, как создать ProgressBar и как с ним работать, но не могу понять, как добиться прогресса WebView / WebEngine.Как получить прогресс для обновления ProgressBar?

Ответы [ 2 ]

0 голосов
/ 16 февраля 2019

Из документации 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;
    }

}
0 голосов
/ 16 февраля 2019

Вы можете сделать это, как показано ниже:

Метод для извлечения задач с использованием фонового потока, 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();

Одна и та же Служба может быть повторно использована несколько раз (вызовите метод cancel () и start () или restart ()), в то время как Задача может использоваться только один раз (Служба будет каждый раз создавать новую Задачу).это начинается).

...