Как обновить индикатор прогресса JavaFX на основе прогресса отдельных классов? - PullRequest
0 голосов
/ 03 марта 2019

У меня есть программа, состоящая из 4 классов:

1) GUI.java - Программа, содержащая индикатор прогресса JavaFX GUI

2) mainRun.java - мастер-класс, который запускает task1.java и task2.java.В реальной программе mainRun.java будет отвечать за объединение нескольких данных из task1.java и task2.java, следовательно, этот класс необходим.

3) task1.java - Aпрограмма, которая будет запускаться ДО Task2.java

4) task2.java - Программа, которая будет запускаться ПОСЛЕ task1.java

Я хотел бы обновить GUI.javaИндикатор, основанный на функции updateProgress (X, Y) из task1.java и task2.java.

Однако mainRun.java будет программой, вызывающей task1.java и после, task2.java.Следовательно, индикатор прогресса GUI.java будет обновлять свой прогресс только на основе функции updateProgress (X, Y), вызываемой из mainRun.java.

Как я могу обновлять индикатор прогресса GUI.java всякий раз, когда updateProgress (X, Y) функция запускается в task1.java и task2.java (возможно, в обход mainRun.java?)?

В противном случае, есть ли способ, где mainRun.java может быть активно уведомлен оupdateProgress (X, Y) из task1.java и task2.java и обновлять индикатор прогресса GUI.java при получении уведомления?

Вот пример ложного примера описываемой мной проблемы:

GUI.java

public class GUI extends Application {
   private mainRun mainTask;
   @Override
   public void start(Stage primaryStage) {
       final ProgressIndicator progressIndicator = new ProgressIndicator(0);
       final Button startButton = new Button("Start");

       // Start Button.
       startButton.setOnAction(new EventHandler<ActionEvent>() {
           @Override
           public void handle(ActionEvent event) {
               mainTask = new mainRun();
               progressIndicator.progressProperty().unbind();
               progressIndicator.setProgress(0);
               progressIndicator.progressProperty().unbind();
            progressIndicator.progressProperty().bind(mainTask.progressProperty());
               new Thread(mainTask).start();
           }
       });
       ... JavaFX stage code ...
   }
}

mainRun.java

public class CopyTask extends Task<String> {

@Override
protected String call() throws Exception {

    /** Update GUI.java's progress bar based on t1 here **/

    task1 t1 = new task1();
    ProgressIndicator progress = new ProgressIndicator(0);
    progress.progressProperty().unbind();
    progress.setProgress(0);
    progress.progressProperty().bind(t1.progressProperty());

    new Thread(t1).start();
    t1.addEventHandler(WorkerStateEvent.WORKER_STATE_SUCCEEDED, //
          new EventHandler<WorkerStateEvent>() {

              @Override
              public void handle(WorkerStateEvent t) {

              /** Continue updating GUI.java's progress bar based on t2 here **/

                  task2 t2 = new task2();
                  progress.progressProperty().unbind();
                  progress.progressProperty().bind(t2.progressProperty());
                  new Thread(t2).start();
              }
          });
        return "Done";
    } 
}

task1.java

public class task1 extends Task<String> {
    protected String call() throws Exception {
        for (int i =0; i<1000; i++) {
            this.updateProgress(i,2000); // currently updates mainRun.java progress bar NOT GUI.java
        }
    return "";
    } 
}

task2.java

public class task2 extends Task<String> {
    protected String call() throws Exception {
        for (int i =1000; i<2000; i++) {
            this.updateProgress(i,2000); // currently updates mainRun.java progress bar NOT GUI.java
        }
    return "";
}

ОБНОВЛЕНИЕ: Нашли решение благодаря пользователю c0der:

progressIndicator.progressProperty (). Bind (copyTask.t1.progressProperty (). Add (copyTask.t2.progressProperty ())); **

ОБНОВЛЕНИЕ: Найден этот поток , который отлично решил все проблемы на твердом примере.

1 Ответ

0 голосов
/ 03 марта 2019

Вы делаете это, привязывая свойство прогресса прогрессбара к двум свойствам прогресса:

import java.util.concurrent.TimeUnit;
import javafx.application.Application;
import javafx.concurrent.Task;
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.layout.BorderPane;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class TwoLongProcessWithOneProgressBar extends Application {

    @Override
    public void start(Stage stage) throws InterruptedException {

        BorderPane mainPane = new BorderPane();

        FlowPane topPane = new FlowPane(Orientation.HORIZONTAL, 5.,5.);
        topPane.setPadding(new Insets(20.));

        Panel panel = new Panel();
        BorderPane.setAlignment(panel, Pos.CENTER);

        Button button = new Button("Start");
        button.setDefaultButton(true);
        button.setOnAction(e -> {
            panel.runLlongTask();
            button.setDisable(true);
        });
        topPane.getChildren().add(button);
        mainPane.setTop(topPane);

        mainPane.setCenter(panel);
        mainPane.setBottom(panel.getBar());

        Scene scene = new Scene(mainPane, Color.WHITE);
        stage.setScene(scene);
        stage.centerOnScreen();
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

class Panel extends HBox{

    private final ProgressBar bar;

    Panel(){
        setPrefSize(150,50);
        bar = new ProgressBar();
        bar.prefWidthProperty().bind(widthProperty());
    }

    void runLlongTask() {
        Task task1 = new Task1();
        Thread th1 = new Thread(task1);
        th1.setDaemon(true);

        Task task2 = new Task2();
        Thread th2 = new Thread(task2);
        th2.setDaemon(true);
        //bind progress bar to both task progress property
        bar.progressProperty().bind(task1.progressProperty().add(task2.progressProperty()));
        th1.start();
        th2.start();
    }

    ProgressBar getBar() {  return bar; }
}

class Task1 extends Task<Void>{
    @Override
    protected Void call() throws Exception {
        for (int i =0; i<1000; i++) {
            TimeUnit.MILLISECONDS.sleep(100);
            updateProgress(i,2000);
        }
        return null;
    }
}

class Task2 extends Task<Void>{
    @Override
    protected Void call() throws Exception {
        for (int i =0; i<1000; i++) {
            TimeUnit.MILLISECONDS.sleep(100);
            updateProgress(i,2000);
        }
        return null;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...