gpt4 book ai didi

javafx - 在 JavaFX 中显示带有 ProgressBar 的弹出窗口

转载 作者:行者123 更新时间:2023-12-03 16:35:09 25 4
gpt4 key购买 nike

如何通过弹出窗口显示我的进度条并在过程完成后自动关闭。这是我的代码。

 Task<ProgressForm> task = new Task<ProgressForm>() {
@Override
public ProgressForm call() throws InterruptedException{
ProgressForm pf = new ProgressForm();
for (int i = 1; i <= 10; i++) {
pf.activateProgressBar(this);
updateProgress(i, 10);
}
return pf;
}
};

task.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
@Override
public void handle(WorkerStateEvent t) {
ProgressForm pf = (ProgressForm)task.getValue();
pf.getDialogStage().close();
}
});

Thread th = new Thread(task);
th.run();

进度表类:
private final Stage dialogStage;
private final ProgressBar pb = new ProgressBar();
private final ProgressIndicator pin = new ProgressIndicator();

public ProgressForm() {
dialogStage = new Stage();
dialogStage.initStyle(StageStyle.UTILITY);
dialogStage.setResizable(false);
dialogStage.initModality(Modality.APPLICATION_MODAL);

// PROGRESS BAR
final Label label = new Label();
label.setText("alerto");

pb.setProgress(-1F);
pin.setProgress(-1F);

final HBox hb = new HBox();
hb.setSpacing(5);
hb.setAlignment(Pos.CENTER);
hb.getChildren().addAll(pb, pin);

Scene scene = new Scene(hb);
dialogStage.setScene(scene);
}

public void activateProgressBar(final Task task) throws InterruptedException {
pb.progressProperty().bind(task.progressProperty());
pin.progressProperty().bind(task.progressProperty());
dialogStage.show();
}

public Stage getDialogStage() {
return dialogStage;
}

这段代码的问题是
  • 如果我使用 .show(),显示弹出窗口很流畅,但没有进度条。
  • 如果我使用 .showAndWait(),显示弹出窗口需要手动退出弹出窗口以关闭但进度条显示。

  • 对此有任何想法/想法吗?

    最佳答案

    JavaFX 中多线程的两条规则是:

  • 修改 UI 的代码(创建 Stage 或更改属性
    作为场景图一部分的节点)必须被执行在
    JavaFX 应用程序线程。违反此规则将抛出IllegalStateException s 或导致不可预测的行为。
  • 执行时间较长的代码应该 在后台线程中执行(即不是 FX 应用程序线程)。违反此规则将导致 UI 无响应。

  • 您的代码违反了第一条规则,因为它调用了 ProgressForm后台线程中的构造函数。您应该首先设置 UI,显示对话框,然后启动后台线程。

    注意不需要重复绑定(bind) progress progress 的进度条和指示器的属性任务的属性。一旦绑定(bind),它将保持绑定(bind),直到并且除非您取消绑定(bind)。

    修复你的代码是相当困难的,因为你的后台任务实际上并没有做任何需要任何时间的事情。这是您正在做的事情的一个版本,只需暂停一下:
    import javafx.application.Application;
    import javafx.concurrent.Task;
    import javafx.geometry.Pos;
    import javafx.scene.Scene;
    import javafx.scene.control.Button;
    import javafx.scene.control.Label;
    import javafx.scene.control.ProgressBar;
    import javafx.scene.control.ProgressIndicator;
    import javafx.scene.layout.HBox;
    import javafx.scene.layout.StackPane;
    import javafx.stage.Modality;
    import javafx.stage.Stage;
    import javafx.stage.StageStyle;

    public class ProgressDialogExample extends Application {

    @Override
    public void start(Stage primaryStage) {
    Button startButton = new Button("Start");
    startButton.setOnAction(e -> {
    ProgressForm pForm = new ProgressForm();

    // In real life this task would do something useful and return
    // some meaningful result:
    Task<Void> task = new Task<Void>() {
    @Override
    public Void call() throws InterruptedException {
    for (int i = 0; i < 10; i++) {
    updateProgress(i, 10);
    Thread.sleep(200);
    }
    updateProgress(10, 10);
    return null ;
    }
    };

    // binds progress of progress bars to progress of task:
    pForm.activateProgressBar(task);

    // in real life this method would get the result of the task
    // and update the UI based on its value:
    task.setOnSucceeded(event -> {
    pForm.getDialogStage().close();
    startButton.setDisable(false);
    });

    startButton.setDisable(true);
    pForm.getDialogStage().show();

    Thread thread = new Thread(task);
    thread.start();
    });

    StackPane root = new StackPane(startButton);
    Scene scene = new Scene(root, 350, 75);
    primaryStage.setScene(scene);
    primaryStage.show();

    }

    public static class ProgressForm {
    private final Stage dialogStage;
    private final ProgressBar pb = new ProgressBar();
    private final ProgressIndicator pin = new ProgressIndicator();

    public ProgressForm() {
    dialogStage = new Stage();
    dialogStage.initStyle(StageStyle.UTILITY);
    dialogStage.setResizable(false);
    dialogStage.initModality(Modality.APPLICATION_MODAL);

    // PROGRESS BAR
    final Label label = new Label();
    label.setText("alerto");

    pb.setProgress(-1F);
    pin.setProgress(-1F);

    final HBox hb = new HBox();
    hb.setSpacing(5);
    hb.setAlignment(Pos.CENTER);
    hb.getChildren().addAll(pb, pin);

    Scene scene = new Scene(hb);
    dialogStage.setScene(scene);
    }

    public void activateProgressBar(final Task<?> task) {
    pb.progressProperty().bind(task.progressProperty());
    pin.progressProperty().bind(task.progressProperty());
    dialogStage.show();
    }

    public Stage getDialogStage() {
    return dialogStage;
    }
    }

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

    关于javafx - 在 JavaFX 中显示带有 ProgressBar 的弹出窗口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29625170/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com