java - JavaFx ProgressIndicator while Loading Pane (GUI) -


in application, have build big panes lot of content. show progressindicator while gui loading.

my first test, show progressindicator while adding lot of tabs tabpane.

that's test code:

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         {         (int = 1; < 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();     } } 

but application show window if task has finished. if replace lines inside for-loop thread.sleep(10) application show indicator and, after all, sleep, shows gui.

how can show indicator while gui not loaded already?

you have task creates result (i.e. tabpane). therefore it's more convenient use tabpane type parameter instead of void should call updateprogress update progress property , bind property the progress property of progressindicator.

the result can added borderpane in onsucceded handler instead of creating (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;             (int = 1; <= count; i++) {                 thread.sleep(10);                 tab newtab = new tab("number:" + i);                 tabs.add(newtab);                 updateprogress(i, count);             }             return tabpane;         }     };     mylongtask.setonsucceeded(evt -> {         // update ui results         tabpane = mylongtask.getvalue();         borderpane.setcenter(new pane(tabpane));     });      // add progress indicator show progress of mylongtask     myprogressindicator = new progressindicator();     myprogressindicator.progressproperty().bind(mylongtask.progressproperty());     borderpane.setcenter(new pane(myprogressindicator));      new thread(mylongtask).start(); } 

simply creating tabs fast however, , won't see progress indicator in ui. layouting tabpane 999 tabs rather slow. ui freeze short time. can work around adding limited number of tabs in each frame:

return list<tab> task instead of tabpane; these tabs should not added tabpane (yet). can use animationtimer add fixed number of tabs each frame:

final list<tab> result = ...; // 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(); 

Comments