【问题标题】:Binding a Timeline or Task to a ProgressBar?将时间线或任务绑定到进度条?
【发布时间】:2015-10-05 10:02:38
【问题描述】:

在实现 JavaFX 进度条/指示器的progressProperty绑定时,任务或 JavaFX 时间线之间是否存在“首选”方法?

例如,此代码加载一个屏幕,其中包含由按钮触发的 2 个进度条。一个 (progressBar) 的进度受任务约束,而另一个 (progressBar2) 受时间线约束。

public class TaskTest extends Application {
  public static void main(String[] args) throws Exception { launch(args); }
  public void start(final Stage stage) throws Exception {
    final Button runButton = new Button("Run");
    final ProgressBar progressBar = new ProgressBar();

    final ProgressBar progressBar2 = new ProgressBar();
    Integer START_TIME = 11;
    Timeline timeline = new Timeline();
    IntegerProperty timeSeconds = new SimpleIntegerProperty((START_TIME) * 100);

    runButton.setOnAction(new EventHandler<ActionEvent>() {
      @Override 
      public void handle(ActionEvent actionEvent) {
        final Task task = new Task<Object>() {
          @Override 
          protected Object call() throws InterruptedException {
            for (int i = 0; i < 11; i++) {
              Thread.sleep(1000);
              updateProgress(i+1, 11);
            }
            return true;
          }
        };

        runButton.disableProperty().bind(task.runningProperty());
        progressBar.progressProperty().bind(task.progressProperty());
        task.stateProperty().addListener(new ChangeListener<Worker.State>() {
          @Override 
          public void changed(ObservableValue<? extends Worker.State> observableValue, Worker.State oldState, Worker.State newState) {
            if (newState == Worker.State.SUCCEEDED) {
              System.out.println("This is ok, this thread " + Thread.currentThread() + " is the JavaFX Application thread.");
              runButton.setText("Voila!");
            }
          }
        });
        new Thread(task).start();

        //Timeline
        progressBar2.progressProperty().bind(timeSeconds.divide((START_TIME) * 100.0).subtract(1).multiply(-1));
        if (timeline != null){
            timeline.stop();
        }
        timeSeconds.set((START_TIME) * 100);
        timeline.getKeyFrames().add(
                new KeyFrame(Duration.seconds(START_TIME), new KeyValue(timeSeconds, 0)));
        timeline.playFromStart();
        timeline.setOnFinished(new EventHandler<ActionEvent>(){
            @Override
            public void handle(ActionEvent event) {
                System.out.println("DONE");
            }
        });
      }
    });

    VBox layout = new VBox();
    layout.getChildren().addAll(runButton,progressBar,progressBar2);
    layout.setStyle("-fx-background-color: cornsilk; -fx-padding:10; -fx-font-size: 16;");
    Scene scene = new Scene(layout);
    stage.setScene(scene);
    stage.show();
  }
}

progressBar2progressBar 有更多的'flow',后者在'块'中更新。这可以通过简单地更改减少 `Thread.sleep(1000)' 的值来防止。这是好习惯吗?

在我看来,使用时间线比使用任务更简单、更有效。

我应该使用什么,更重要的是为什么?

【问题讨论】:

    标签: java javafx progress-bar


    【解决方案1】:
    1. 当您想要显示与任务相关的某事的进度时,请使用链接到 TaskProgressBar

      • 例如,测量文件上传任务中处理的字节数。
    2. 当不涉及任何任务时,使用链接到 Timeline 的 ProgressBar。

      • 例如,显示倒计时进度计时器,供用户在定时测验中回答多项选择题。

    在另一个线程上执行冗长的计算或阻塞 I/O 进程将需要一个任务。如果您没有其中任何一个,那么您不需要任务。

    当您有任务时,任务 API 会提供一个 progress property,您可以以线程安全的方式将进度条的值绑定到该 progress property

    任务的进度不需要与进度以恒定速率变化的固定时间段相关。例如,文件上传传输的字节吞吐量和文件上传的总时间可能会因网络速度不一致而有所不同。通过将任务的进度与传输的字节数联系起来,进度条将显示为任务完成的总工作量的真实度量。仅使用时间线无法准确得出此信息。

    如果您使用时间线,则可以在时间线中将进度条的 value 属性指定为 KeyValue,您可能会发现它比您当前使用的代码更简单。

    【讨论】:

    • 如何将任务进度与传输的字节数联系起来?
    • @CorrOrtiz 只需使用数学。如果您做不到,请创建一个包含code for your attempt 的新问题。
    • 我在这里提出一个新问题,解释我的情况link@jewelsea
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-02
    • 1970-01-01
    相关资源
    最近更新 更多