JavaFx ProgressIndicator while Loading Pane (GUI)

后端 未结 2 545
我寻月下人不归
我寻月下人不归 2021-01-17 00:56

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

My first test, I will show a ProgressIn

2条回答
  •  粉色の甜心
    2021-01-17 01:30

    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.

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

    Task myLongTask;
    
    @Override
    public void initialize(URL url, ResourceBundle rb) {
    
        myLongTask = new Task() {
    
            @Override
            protected TabPane call() throws Exception {
                TabPane tabPane = new TabPane();
                List 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();
    }
    

    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:

    Return a List 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 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();
    

提交回复
热议问题