用于显示未在 JavaFX 中显示的 ProgressBar 的弹出窗口
Popup intended to display ProgressBar not showing in JavaFX
我想在 JavaFX 中使用 Popup
显示 ProgressBar
,这样我就可以通过调用 PopUp
的 hide()
方法。但是,ProgessBar
并没有在后台任务完成时消失,而是根本不显示。
import javafx.application.Application;
import javafx.concurrent.Task;
import javafx.scene.Scene;
import javafx.scene.control.ProgressBar;
import javafx.scene.layout.StackPane;
import javafx.stage.Popup;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage stage) {
StackPane root = new StackPane();
Popup popup = new Popup();
ProgressBar bar = new ProgressBar();
popup.getContent().add(bar);
Task<Void> task = new Task<>() {
@Override
protected Void call() {
for (int i = 0; i < 100; i++) {
try {
Thread.sleep(100);
updateProgress(i, 100);
} catch (Exception ignored) {
}
}
return null;
}
};
bar.progressProperty().bind(task.progressProperty());
task.setOnSucceeded(workerStateEvent -> popup.hide());
popup.show(stage);
new Thread(task).start();
stage.setScene(new Scene(root, 100, 100));
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
当我运行上面的代码时,我看到的只是一个空白阶段,如下所示:
如果我使用 root.getChildren().add(bar)
手动将 ProgressBar
添加到 Stage
,该条显示正确,其 progressProperty
正确绑定,所以我知道问题所在与Popup
。但是,使用该方法,当后台任务完成时,该条不会消失。
我在任何地方都找不到这个记录,但我认为 Popup
的所有者必须显示 Popup.show(owner)
方法才能成功。因此,您的代码的以下重新排序(在 popup.show(stage)
之前调用 stage.show()
)有效:
@Override
public void start(Stage stage) {
StackPane root = new StackPane();
Popup popup = new Popup();
ProgressBar bar = new ProgressBar();
popup.getContent().add(bar);
Task<Void> task = new Task<>() {
@Override
protected Void call() {
for (int i = 0; i < 100; i++) {
try {
Thread.sleep(100);
updateProgress(i, 100);
} catch (Exception ignored) {
}
}
return null;
}
};
bar.progressProperty().bind(task.progressProperty());
task.setOnSucceeded(workerStateEvent -> popup.hide());
stage.setScene(new Scene(root, 100, 100));
stage.show();
popup.show(stage);
new Thread(task).start();
}
请注意您的其他方法有效:您只需在任务完成时从场景图中删除进度条即可:
@Override
public void start(Stage stage) {
StackPane root = new StackPane();
// Popup popup = new Popup();
ProgressBar bar = new ProgressBar();
// popup.getContent().add(bar);
root.getChildren().add(bar);
Task<Void> task = new Task<>() {
@Override
protected Void call() {
for (int i = 0; i < 100; i++) {
try {
Thread.sleep(100);
updateProgress(i, 100);
} catch (Exception ignored) {
}
}
return null;
}
};
bar.progressProperty().bind(task.progressProperty());
// task.setOnSucceeded(workerStateEvent -> popup.hide());
task.setOnSucceeded(event -> root.getChildren().remove(bar));
stage.setScene(new Scene(root, 100, 100));
stage.show();
// popup.show(stage);
new Thread(task).start();
}
我想在 JavaFX 中使用 Popup
显示 ProgressBar
,这样我就可以通过调用 PopUp
的 hide()
方法。但是,ProgessBar
并没有在后台任务完成时消失,而是根本不显示。
import javafx.application.Application;
import javafx.concurrent.Task;
import javafx.scene.Scene;
import javafx.scene.control.ProgressBar;
import javafx.scene.layout.StackPane;
import javafx.stage.Popup;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage stage) {
StackPane root = new StackPane();
Popup popup = new Popup();
ProgressBar bar = new ProgressBar();
popup.getContent().add(bar);
Task<Void> task = new Task<>() {
@Override
protected Void call() {
for (int i = 0; i < 100; i++) {
try {
Thread.sleep(100);
updateProgress(i, 100);
} catch (Exception ignored) {
}
}
return null;
}
};
bar.progressProperty().bind(task.progressProperty());
task.setOnSucceeded(workerStateEvent -> popup.hide());
popup.show(stage);
new Thread(task).start();
stage.setScene(new Scene(root, 100, 100));
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
当我运行上面的代码时,我看到的只是一个空白阶段,如下所示:
如果我使用 root.getChildren().add(bar)
手动将 ProgressBar
添加到 Stage
,该条显示正确,其 progressProperty
正确绑定,所以我知道问题所在与Popup
。但是,使用该方法,当后台任务完成时,该条不会消失。
我在任何地方都找不到这个记录,但我认为 Popup
的所有者必须显示 Popup.show(owner)
方法才能成功。因此,您的代码的以下重新排序(在 popup.show(stage)
之前调用 stage.show()
)有效:
@Override
public void start(Stage stage) {
StackPane root = new StackPane();
Popup popup = new Popup();
ProgressBar bar = new ProgressBar();
popup.getContent().add(bar);
Task<Void> task = new Task<>() {
@Override
protected Void call() {
for (int i = 0; i < 100; i++) {
try {
Thread.sleep(100);
updateProgress(i, 100);
} catch (Exception ignored) {
}
}
return null;
}
};
bar.progressProperty().bind(task.progressProperty());
task.setOnSucceeded(workerStateEvent -> popup.hide());
stage.setScene(new Scene(root, 100, 100));
stage.show();
popup.show(stage);
new Thread(task).start();
}
请注意您的其他方法有效:您只需在任务完成时从场景图中删除进度条即可:
@Override
public void start(Stage stage) {
StackPane root = new StackPane();
// Popup popup = new Popup();
ProgressBar bar = new ProgressBar();
// popup.getContent().add(bar);
root.getChildren().add(bar);
Task<Void> task = new Task<>() {
@Override
protected Void call() {
for (int i = 0; i < 100; i++) {
try {
Thread.sleep(100);
updateProgress(i, 100);
} catch (Exception ignored) {
}
}
return null;
}
};
bar.progressProperty().bind(task.progressProperty());
// task.setOnSucceeded(workerStateEvent -> popup.hide());
task.setOnSucceeded(event -> root.getChildren().remove(bar));
stage.setScene(new Scene(root, 100, 100));
stage.show();
// popup.show(stage);
new Thread(task).start();
}