加载窗格(GUI)时的JavaFx ProgressIndicator [英] JavaFx ProgressIndicator while Loading Pane (GUI)

查看:763
本文介绍了加载窗格(GUI)时的JavaFx ProgressIndicator的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的应用程序中,我必须构建包含大量内容的大窗格。我将在加载GUI时显示一个ProgressIndicator。

In my application, I have to build big panes with a lot of content. I will show a ProgressIndicator while the GUI is loading.

我的第一个测试,我将在TabPane中添加大量标签时显示ProgressIndicator。

My first test, I will show a ProgressIndicator while I adding a lot of tabs into a TabPane.

这是我的测试代码:

public class SampleController implements Initializable {
    private TabPane tabPane;
    @FXML
    private BorderPane borderPane;

    ProgressIndicator myProgressIndicator;
    Task<Void> myLongTask;


    @Override
    public void initialize(URL location, ResourceBundle resources)
    {
        myProgressIndicator = new ProgressIndicator();
        Pane p1 = new Pane(myProgressIndicator);
        tabPane = new TabPane();
        Pane p2 = new Pane(tabPane);


        myLongTask = new Task<Void>()
        {
        @Override
        protected Void call() throws Exception
        {
        for (int i = 1; i < 1000; i++)
        {
//          Thread.sleep(10);
            Tab newTab = new Tab("Number:" + i);
            tabPane.getTabs().add(newTab);
        }
        return null;
        }
        };
        borderPane.centerProperty().bind(Bindings.when(myLongTask.runningProperty()).then(p1).otherwise(p2));

        new Thread(myLongTask).start();
    }
}

但如果任务有,应用程序将显示窗口完了。如果我用 Thread.sleep(10)替换for循环中的行,应用程序会显示指标,毕竟,它会显示GUI。

But the application will show the window if the Task has finished. If I replace the lines inside the for-loop with Thread.sleep(10) the application show the Indicator and, after all, sleep, it shows the GUI.

如果GUI尚未加载,我如何显示指标?

How can I show an Indicator while the GUI is not loaded already?

推荐答案

您有一个任务,它会创建一个结果(即 TabPane )。因此,使用 TabPane 作为类型参数而不是 Void 更方便你也应该调用 updateProgress 更新 progress property 并将该属性绑定到 ProgressIndicator 进度属性。

You have a Task that creates a result (i.e. a TabPane). Therefore it's more convenient to use TabPane as type parameter instead of Void also you should call updateProgress to update the progress property and bind that property to the progress property of the ProgressIndicator.

结果可以添加到 BorderPane 。 com / javase / 8 / javafx / api / javafx / concurrent / Task.html#onSucceededPropertyrel =nofollow> onSucceded handler 而不是创建(或多或少)复杂的绑定:

The result can be added to the BorderPane in the onSucceded handler instead of creating a (more or less) complicated binding:

Task<TabPane> myLongTask;

@Override
public void initialize(URL url, ResourceBundle rb) {

    myLongTask = new Task<TabPane>() {

        @Override
        protected TabPane call() throws Exception {
            TabPane tabPane = new TabPane();
            List<Tab> tabs = tabPane.getTabs();
            final int count = 1000 - 1;
            for (int i = 1; i <= count; i++) {
                Thread.sleep(10);
                Tab newTab = new Tab("Number:" + i);
                tabs.add(newTab);
                updateProgress(i, count);
            }
            return tabPane;
        }
    };
    myLongTask.setOnSucceeded(evt -> {
        // update ui with results
        tabPane = myLongTask.getValue();
        borderPane.setCenter(new Pane(tabPane));
    });

    // add progress indicator to show progress of myLongTask
    myProgressIndicator = new ProgressIndicator();
    myProgressIndicator.progressProperty().bind(myLongTask.progressProperty());
    borderPane.setCenter(new Pane(myProgressIndicator));

    new Thread(myLongTask).start();
}

然而,简单地创建选项卡很快,您将看不到任何进展用户界面中的指标。使用999 Tabs 布置 TabPane 但是相当慢。用户界面很可能会在很短的时间内冻结。您可以通过在每个帧中仅添加有限数量的 Tab 来解决此问题:

Simply creating the tabs is fast however, and you won't see any progress indicator in the UI. Layouting a TabPane with 999 Tabs however is rather slow. The UI will most likely freeze for a short time. You can work around this by adding only a limited number of Tabs in each frame:

返回从任务列出< Tab> 而不是 TabPane ;这些 Tab 不应添加到 TabPane (还)。您可以使用 AnimationTimer 每帧添加固定数量的标签:

Return a List<Tab> from the task instead of a TabPane; these Tabs should not be added to the TabPane (yet). You can use a AnimationTimer to add a fixed number of tabs each frame:

final List<Tab> result = ...; // your tab list

// number of elements added each frame
final int step = 5;

final int size = result.size();
AnimationTimer timer = new AnimationTimer() {

    int index = 0;

    @Override
    public void handle(long now) {
        tabPane.getTabs().addAll(result.subList(index, Math.min(size, index+step)));
        index += step;
        if (index >= size) {
            this.stop();
        }
    }
};
timer.start();

这篇关于加载窗格(GUI)时的JavaFx ProgressIndicator的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆