弹出的用于显示进度条的窗口在JavaFX中未显示出来。

huangapple go评论61阅读模式
英文:

Popup intended to display ProgressBar not showing in JavaFX

问题

我想在JavaFX中使用Popup来显示一个ProgressBar,以便我可以通过调用Popuphide()方法来使ProgressBar消失。然而,与其在后台任务完成时消失,ProgressBar根本不显示。

当我运行上面的代码时,我只看到一个空白的舞台,如下所示:

如果我使用root.getChildren().add(bar)ProgressBar手动添加到Stage中,进度条将正确显示,并且其progressProperty正确绑定,因此我知道问题出在Popup上。然而,使用该方法,进度条在后台任务完成时不会消失。

英文:

I want to display a ProgressBar using a Popup in JavaFX so that I will be able to make the ProgressBar disappear by calling the PopUp's hide() method. However, rather than disappearing when the background task is complete, the ProgessBar doesn't show at all.

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);
    }
}

When I run the above code, all I see is a blank stage, shown here:
弹出的用于显示进度条的窗口在JavaFX中未显示出来。

If I add the ProgressBar to the Stage manually using root.getChildren().add(bar), the bar displays correctly, with its progressProperty properly bonded, so I know that the issue is with the Popup. However, using that method, the bar doesn't disappear when the background task is complete.

答案1

得分: 3

以下是翻译好的部分:

"我无法在任何地方找到这个记录,但我认为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();
}
英文:

I can't find this documented anywhere, but I think the owner of a Popup must be showing for the Popup.show(owner) method to succeed. So the following reordering of your code (calling stage.show() before popup.show(stage)) works:

@Override
public void start(Stage stage) {
StackPane root = new StackPane();
Popup popup = new Popup();
ProgressBar bar = new ProgressBar();
popup.getContent().add(bar);
Task&lt;Void&gt; task = new Task&lt;&gt;() {
@Override
protected Void call() {
for (int i = 0; i &lt; 100; i++) {
try {
Thread.sleep(100);
updateProgress(i, 100);
} catch (Exception ignored) {
}
}
return null;
}
};
bar.progressProperty().bind(task.progressProperty());
task.setOnSucceeded(workerStateEvent -&gt; popup.hide());
stage.setScene(new Scene(root, 100, 100));
stage.show();
popup.show(stage);
new Thread(task).start();
}

Note your other approach works: you just have to remove the progress bar from the scene graph when the task is complete:

    @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&lt;Void&gt; task = new Task&lt;&gt;() {
@Override
protected Void call() {
for (int i = 0; i &lt; 100; i++) {
try {
Thread.sleep(100);
updateProgress(i, 100);
} catch (Exception ignored) {
}
}
return null;
}
};
bar.progressProperty().bind(task.progressProperty());
//        task.setOnSucceeded(workerStateEvent -&gt; popup.hide());
task.setOnSucceeded(event -&gt; root.getChildren().remove(bar));
stage.setScene(new Scene(root, 100, 100));
stage.show();
//        popup.show(stage);
new Thread(task).start();
}

huangapple
  • 本文由 发表于 2020年8月6日 21:17:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/63284460.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定