java - 用于显示 ProgressBar 的弹出窗口未在 JavaFX 中显示

标签 java multithreading javafx popup progress-bar

我想显示ProgressBar使用Popup在 JavaFX 中,这样我就能够制作 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);
    }
}

当我运行上面的代码时,我看到的只是一个空白的阶段,如下所示: Blank stage in place of ProgressBar

如果我添加ProgressBarStage手动使用root.getChildren().add(bar) ,条形图正确显示,其 progressProperty正确绑定(bind),所以我知道问题出在 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();

    }

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

相关文章:

java - 为 java android 的 if 条件做更简单的方法

java - 仅以编程方式更改 TextView 中某些文本的背景颜色

Java:ArrayList 瓶颈

java - 有什么好的示例程序可以演示对 Thread.sleep() 抛出的 InterruptedException 的不当处理?

Java getResourceAsStream 返回 NullPointerException?

java - Java 中如何序列化属性?

multithreading - 如何跨线程共享引用?

java - 将异常从一个线程重新抛出到另一个线程

java - 如何区分JavaFX中的左/右shift、ctrl、alt和enter键?

java - 如何全局禁用默认上下文菜单