Display ProgressBar while dynamically loading GridPane










1















Heyyo,



So I'm currently working on a JavaFX project, with another Java project handling/serving the data for said project.



While I got most things working, I am still trying to get a ProgressBar to load while loading the data from the data project, which I am having some issues doing.



Currently, I'm looping through the data, creating/adding labels to a GridPane for each "entry". Above it, I declare a JavaFX ProgressBar and add it to my "root wrapper" VBox.



 GridPane wrapper = new GridPane();
ProgressBar progress = new ProgressBar();
viewBox.getChildren().add(progress);

int currentRow = 1;
for(Map.Entry<String, List<Observation>> item : handler.get(from, to).entrySet())
if(item != null)
for(Observation inner : item.getValue())
if(inner != null)
// Add the data for the datalist
wrapper.add(new Label(item.getKey()), 0, currentRow);
wrapper.add(new Label(inner.getDate().toString()), 1, currentRow);
wrapper.add(new Label(String.valueOf(inner.getValue())), 2, currentRow);

currentRow++;





viewBox.getChildren().add(wrapper);


Now, to the things I have tried to achieve this, as I realise this code alone won't do much:



1) Tried wrapping the GridPane in a Task and creating a new thread from said task - Didn't work due to trying to create JavaFX elements while not being in the JavaFX Application Thread



2) Tried wrapping all of the wrapper.add(new Label(...)); in Platform.runLater() - As wrapper is not final and needs to exist both inside and outside of the scope, this did not work either.



3) Tried adding the data entry-by-entry to a temporary map and showing the progress that way by letting the ProgressBar-part run in it's own Task/Thread. Seemed to work as long as I used Thread.join(); afterwards, but seems extremely ineffective.



As always, any and all help is appreciated. If I forgot to mention something required to be able to tell what's going on, please do let me know! I've tried to include everything relevant.



Thanks in advance!










share|improve this question






















  • If I understand it correctly, you want to update a progressbar every time a "data" has been loaded? You should also show whether the code above is on the application thread or not.

    – Andreas
    Nov 14 '18 at 13:06












  • I want a progressbar that loads and "finishes" when the loop on the 6th row is finished, is a way to put it I guess. The code snippet is all currently in the application thread. @Andreas

    – Xariez
    Nov 14 '18 at 13:34











  • Regarding "1)", there are only a few JavaFX GUI objects that must be created on the FX thread; most of the objects are capable of being created and modified (so long as they aren't part of a scene-graph) on any single thread.

    – Slaw
    Nov 14 '18 at 13:35
















1















Heyyo,



So I'm currently working on a JavaFX project, with another Java project handling/serving the data for said project.



While I got most things working, I am still trying to get a ProgressBar to load while loading the data from the data project, which I am having some issues doing.



Currently, I'm looping through the data, creating/adding labels to a GridPane for each "entry". Above it, I declare a JavaFX ProgressBar and add it to my "root wrapper" VBox.



 GridPane wrapper = new GridPane();
ProgressBar progress = new ProgressBar();
viewBox.getChildren().add(progress);

int currentRow = 1;
for(Map.Entry<String, List<Observation>> item : handler.get(from, to).entrySet())
if(item != null)
for(Observation inner : item.getValue())
if(inner != null)
// Add the data for the datalist
wrapper.add(new Label(item.getKey()), 0, currentRow);
wrapper.add(new Label(inner.getDate().toString()), 1, currentRow);
wrapper.add(new Label(String.valueOf(inner.getValue())), 2, currentRow);

currentRow++;





viewBox.getChildren().add(wrapper);


Now, to the things I have tried to achieve this, as I realise this code alone won't do much:



1) Tried wrapping the GridPane in a Task and creating a new thread from said task - Didn't work due to trying to create JavaFX elements while not being in the JavaFX Application Thread



2) Tried wrapping all of the wrapper.add(new Label(...)); in Platform.runLater() - As wrapper is not final and needs to exist both inside and outside of the scope, this did not work either.



3) Tried adding the data entry-by-entry to a temporary map and showing the progress that way by letting the ProgressBar-part run in it's own Task/Thread. Seemed to work as long as I used Thread.join(); afterwards, but seems extremely ineffective.



As always, any and all help is appreciated. If I forgot to mention something required to be able to tell what's going on, please do let me know! I've tried to include everything relevant.



Thanks in advance!










share|improve this question






















  • If I understand it correctly, you want to update a progressbar every time a "data" has been loaded? You should also show whether the code above is on the application thread or not.

    – Andreas
    Nov 14 '18 at 13:06












  • I want a progressbar that loads and "finishes" when the loop on the 6th row is finished, is a way to put it I guess. The code snippet is all currently in the application thread. @Andreas

    – Xariez
    Nov 14 '18 at 13:34











  • Regarding "1)", there are only a few JavaFX GUI objects that must be created on the FX thread; most of the objects are capable of being created and modified (so long as they aren't part of a scene-graph) on any single thread.

    – Slaw
    Nov 14 '18 at 13:35














1












1








1








Heyyo,



So I'm currently working on a JavaFX project, with another Java project handling/serving the data for said project.



While I got most things working, I am still trying to get a ProgressBar to load while loading the data from the data project, which I am having some issues doing.



Currently, I'm looping through the data, creating/adding labels to a GridPane for each "entry". Above it, I declare a JavaFX ProgressBar and add it to my "root wrapper" VBox.



 GridPane wrapper = new GridPane();
ProgressBar progress = new ProgressBar();
viewBox.getChildren().add(progress);

int currentRow = 1;
for(Map.Entry<String, List<Observation>> item : handler.get(from, to).entrySet())
if(item != null)
for(Observation inner : item.getValue())
if(inner != null)
// Add the data for the datalist
wrapper.add(new Label(item.getKey()), 0, currentRow);
wrapper.add(new Label(inner.getDate().toString()), 1, currentRow);
wrapper.add(new Label(String.valueOf(inner.getValue())), 2, currentRow);

currentRow++;





viewBox.getChildren().add(wrapper);


Now, to the things I have tried to achieve this, as I realise this code alone won't do much:



1) Tried wrapping the GridPane in a Task and creating a new thread from said task - Didn't work due to trying to create JavaFX elements while not being in the JavaFX Application Thread



2) Tried wrapping all of the wrapper.add(new Label(...)); in Platform.runLater() - As wrapper is not final and needs to exist both inside and outside of the scope, this did not work either.



3) Tried adding the data entry-by-entry to a temporary map and showing the progress that way by letting the ProgressBar-part run in it's own Task/Thread. Seemed to work as long as I used Thread.join(); afterwards, but seems extremely ineffective.



As always, any and all help is appreciated. If I forgot to mention something required to be able to tell what's going on, please do let me know! I've tried to include everything relevant.



Thanks in advance!










share|improve this question














Heyyo,



So I'm currently working on a JavaFX project, with another Java project handling/serving the data for said project.



While I got most things working, I am still trying to get a ProgressBar to load while loading the data from the data project, which I am having some issues doing.



Currently, I'm looping through the data, creating/adding labels to a GridPane for each "entry". Above it, I declare a JavaFX ProgressBar and add it to my "root wrapper" VBox.



 GridPane wrapper = new GridPane();
ProgressBar progress = new ProgressBar();
viewBox.getChildren().add(progress);

int currentRow = 1;
for(Map.Entry<String, List<Observation>> item : handler.get(from, to).entrySet())
if(item != null)
for(Observation inner : item.getValue())
if(inner != null)
// Add the data for the datalist
wrapper.add(new Label(item.getKey()), 0, currentRow);
wrapper.add(new Label(inner.getDate().toString()), 1, currentRow);
wrapper.add(new Label(String.valueOf(inner.getValue())), 2, currentRow);

currentRow++;





viewBox.getChildren().add(wrapper);


Now, to the things I have tried to achieve this, as I realise this code alone won't do much:



1) Tried wrapping the GridPane in a Task and creating a new thread from said task - Didn't work due to trying to create JavaFX elements while not being in the JavaFX Application Thread



2) Tried wrapping all of the wrapper.add(new Label(...)); in Platform.runLater() - As wrapper is not final and needs to exist both inside and outside of the scope, this did not work either.



3) Tried adding the data entry-by-entry to a temporary map and showing the progress that way by letting the ProgressBar-part run in it's own Task/Thread. Seemed to work as long as I used Thread.join(); afterwards, but seems extremely ineffective.



As always, any and all help is appreciated. If I forgot to mention something required to be able to tell what's going on, please do let me know! I've tried to include everything relevant.



Thanks in advance!







java multithreading javafx






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 14 '18 at 12:53









XariezXariez

599518




599518












  • If I understand it correctly, you want to update a progressbar every time a "data" has been loaded? You should also show whether the code above is on the application thread or not.

    – Andreas
    Nov 14 '18 at 13:06












  • I want a progressbar that loads and "finishes" when the loop on the 6th row is finished, is a way to put it I guess. The code snippet is all currently in the application thread. @Andreas

    – Xariez
    Nov 14 '18 at 13:34











  • Regarding "1)", there are only a few JavaFX GUI objects that must be created on the FX thread; most of the objects are capable of being created and modified (so long as they aren't part of a scene-graph) on any single thread.

    – Slaw
    Nov 14 '18 at 13:35


















  • If I understand it correctly, you want to update a progressbar every time a "data" has been loaded? You should also show whether the code above is on the application thread or not.

    – Andreas
    Nov 14 '18 at 13:06












  • I want a progressbar that loads and "finishes" when the loop on the 6th row is finished, is a way to put it I guess. The code snippet is all currently in the application thread. @Andreas

    – Xariez
    Nov 14 '18 at 13:34











  • Regarding "1)", there are only a few JavaFX GUI objects that must be created on the FX thread; most of the objects are capable of being created and modified (so long as they aren't part of a scene-graph) on any single thread.

    – Slaw
    Nov 14 '18 at 13:35

















If I understand it correctly, you want to update a progressbar every time a "data" has been loaded? You should also show whether the code above is on the application thread or not.

– Andreas
Nov 14 '18 at 13:06






If I understand it correctly, you want to update a progressbar every time a "data" has been loaded? You should also show whether the code above is on the application thread or not.

– Andreas
Nov 14 '18 at 13:06














I want a progressbar that loads and "finishes" when the loop on the 6th row is finished, is a way to put it I guess. The code snippet is all currently in the application thread. @Andreas

– Xariez
Nov 14 '18 at 13:34





I want a progressbar that loads and "finishes" when the loop on the 6th row is finished, is a way to put it I guess. The code snippet is all currently in the application thread. @Andreas

– Xariez
Nov 14 '18 at 13:34













Regarding "1)", there are only a few JavaFX GUI objects that must be created on the FX thread; most of the objects are capable of being created and modified (so long as they aren't part of a scene-graph) on any single thread.

– Slaw
Nov 14 '18 at 13:35






Regarding "1)", there are only a few JavaFX GUI objects that must be created on the FX thread; most of the objects are capable of being created and modified (so long as they aren't part of a scene-graph) on any single thread.

– Slaw
Nov 14 '18 at 13:35













2 Answers
2






active

oldest

votes


















1














After you've created your progressbar and it shows up on your GUI use



progress.setProgress(double value)


with an appropriate value depending on how far you've come in your progress.



As an example, you could put the progress like following:



progress.setProgress((currentRow - 1) / handler.get(from, to).entrySet().size())


This line can be put as first line in your for loop. When the whole job is done set the progress to 1 or remove the progress bar.






share|improve this answer























  • Seems to be working, however also seem to be having some other unexpected errors. Still, answers the question so i'll mark it as the answer! Thanks!

    – Xariez
    Nov 14 '18 at 14:57











  • setProgress should not be called from a background thread.

    – fabian
    Nov 14 '18 at 20:51











  • He commented that it was in the application thread

    – Andreas
    Nov 15 '18 at 20:38


















0














Nodes can be created in any thread, but you must not add them to a scene from a background thread. You shouldn't update properties of nodes in a scene from a background thread either.



GridPane wrapper = new GridPane();
ProgressBar progress = new ProgressBar();
viewBox.getChildren().add(progress);
viewBox.getChildren().add(wrapper);

new Thread(() ->
Collection<Map.Entry<String, List<Observation>>> entries = handler.get(from, to).entrySet();
final double totalEntries = entries.size();
int currentRow = 1;
for(Map.Entry<String, List<Observation>> item : entries)
if(item != null)
for(Observation inner : item.getValue())
if(inner != null)
// Add the data for the datalist
final Node nds = new Node
new Label(item.getKey()),
new Label(inner.getDate().toString()),
new Label(new Label(String.valueOf(inner.getValue())))
;
final double newProgress = currentRow / totalEntries;
final int r = currentRow;
Platform.runLater(() ->
wrapper.addRow(r, nds);
progress.setProgress(newProgress);
);
currentRow++;





).start();





share|improve this answer






















    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53300726%2fdisplay-progressbar-while-dynamically-loading-gridpane%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    1














    After you've created your progressbar and it shows up on your GUI use



    progress.setProgress(double value)


    with an appropriate value depending on how far you've come in your progress.



    As an example, you could put the progress like following:



    progress.setProgress((currentRow - 1) / handler.get(from, to).entrySet().size())


    This line can be put as first line in your for loop. When the whole job is done set the progress to 1 or remove the progress bar.






    share|improve this answer























    • Seems to be working, however also seem to be having some other unexpected errors. Still, answers the question so i'll mark it as the answer! Thanks!

      – Xariez
      Nov 14 '18 at 14:57











    • setProgress should not be called from a background thread.

      – fabian
      Nov 14 '18 at 20:51











    • He commented that it was in the application thread

      – Andreas
      Nov 15 '18 at 20:38















    1














    After you've created your progressbar and it shows up on your GUI use



    progress.setProgress(double value)


    with an appropriate value depending on how far you've come in your progress.



    As an example, you could put the progress like following:



    progress.setProgress((currentRow - 1) / handler.get(from, to).entrySet().size())


    This line can be put as first line in your for loop. When the whole job is done set the progress to 1 or remove the progress bar.






    share|improve this answer























    • Seems to be working, however also seem to be having some other unexpected errors. Still, answers the question so i'll mark it as the answer! Thanks!

      – Xariez
      Nov 14 '18 at 14:57











    • setProgress should not be called from a background thread.

      – fabian
      Nov 14 '18 at 20:51











    • He commented that it was in the application thread

      – Andreas
      Nov 15 '18 at 20:38













    1












    1








    1







    After you've created your progressbar and it shows up on your GUI use



    progress.setProgress(double value)


    with an appropriate value depending on how far you've come in your progress.



    As an example, you could put the progress like following:



    progress.setProgress((currentRow - 1) / handler.get(from, to).entrySet().size())


    This line can be put as first line in your for loop. When the whole job is done set the progress to 1 or remove the progress bar.






    share|improve this answer













    After you've created your progressbar and it shows up on your GUI use



    progress.setProgress(double value)


    with an appropriate value depending on how far you've come in your progress.



    As an example, you could put the progress like following:



    progress.setProgress((currentRow - 1) / handler.get(from, to).entrySet().size())


    This line can be put as first line in your for loop. When the whole job is done set the progress to 1 or remove the progress bar.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Nov 14 '18 at 14:05









    AndreasAndreas

    898




    898












    • Seems to be working, however also seem to be having some other unexpected errors. Still, answers the question so i'll mark it as the answer! Thanks!

      – Xariez
      Nov 14 '18 at 14:57











    • setProgress should not be called from a background thread.

      – fabian
      Nov 14 '18 at 20:51











    • He commented that it was in the application thread

      – Andreas
      Nov 15 '18 at 20:38

















    • Seems to be working, however also seem to be having some other unexpected errors. Still, answers the question so i'll mark it as the answer! Thanks!

      – Xariez
      Nov 14 '18 at 14:57











    • setProgress should not be called from a background thread.

      – fabian
      Nov 14 '18 at 20:51











    • He commented that it was in the application thread

      – Andreas
      Nov 15 '18 at 20:38
















    Seems to be working, however also seem to be having some other unexpected errors. Still, answers the question so i'll mark it as the answer! Thanks!

    – Xariez
    Nov 14 '18 at 14:57





    Seems to be working, however also seem to be having some other unexpected errors. Still, answers the question so i'll mark it as the answer! Thanks!

    – Xariez
    Nov 14 '18 at 14:57













    setProgress should not be called from a background thread.

    – fabian
    Nov 14 '18 at 20:51





    setProgress should not be called from a background thread.

    – fabian
    Nov 14 '18 at 20:51













    He commented that it was in the application thread

    – Andreas
    Nov 15 '18 at 20:38





    He commented that it was in the application thread

    – Andreas
    Nov 15 '18 at 20:38













    0














    Nodes can be created in any thread, but you must not add them to a scene from a background thread. You shouldn't update properties of nodes in a scene from a background thread either.



    GridPane wrapper = new GridPane();
    ProgressBar progress = new ProgressBar();
    viewBox.getChildren().add(progress);
    viewBox.getChildren().add(wrapper);

    new Thread(() ->
    Collection<Map.Entry<String, List<Observation>>> entries = handler.get(from, to).entrySet();
    final double totalEntries = entries.size();
    int currentRow = 1;
    for(Map.Entry<String, List<Observation>> item : entries)
    if(item != null)
    for(Observation inner : item.getValue())
    if(inner != null)
    // Add the data for the datalist
    final Node nds = new Node
    new Label(item.getKey()),
    new Label(inner.getDate().toString()),
    new Label(new Label(String.valueOf(inner.getValue())))
    ;
    final double newProgress = currentRow / totalEntries;
    final int r = currentRow;
    Platform.runLater(() ->
    wrapper.addRow(r, nds);
    progress.setProgress(newProgress);
    );
    currentRow++;





    ).start();





    share|improve this answer



























      0














      Nodes can be created in any thread, but you must not add them to a scene from a background thread. You shouldn't update properties of nodes in a scene from a background thread either.



      GridPane wrapper = new GridPane();
      ProgressBar progress = new ProgressBar();
      viewBox.getChildren().add(progress);
      viewBox.getChildren().add(wrapper);

      new Thread(() ->
      Collection<Map.Entry<String, List<Observation>>> entries = handler.get(from, to).entrySet();
      final double totalEntries = entries.size();
      int currentRow = 1;
      for(Map.Entry<String, List<Observation>> item : entries)
      if(item != null)
      for(Observation inner : item.getValue())
      if(inner != null)
      // Add the data for the datalist
      final Node nds = new Node
      new Label(item.getKey()),
      new Label(inner.getDate().toString()),
      new Label(new Label(String.valueOf(inner.getValue())))
      ;
      final double newProgress = currentRow / totalEntries;
      final int r = currentRow;
      Platform.runLater(() ->
      wrapper.addRow(r, nds);
      progress.setProgress(newProgress);
      );
      currentRow++;





      ).start();





      share|improve this answer

























        0












        0








        0







        Nodes can be created in any thread, but you must not add them to a scene from a background thread. You shouldn't update properties of nodes in a scene from a background thread either.



        GridPane wrapper = new GridPane();
        ProgressBar progress = new ProgressBar();
        viewBox.getChildren().add(progress);
        viewBox.getChildren().add(wrapper);

        new Thread(() ->
        Collection<Map.Entry<String, List<Observation>>> entries = handler.get(from, to).entrySet();
        final double totalEntries = entries.size();
        int currentRow = 1;
        for(Map.Entry<String, List<Observation>> item : entries)
        if(item != null)
        for(Observation inner : item.getValue())
        if(inner != null)
        // Add the data for the datalist
        final Node nds = new Node
        new Label(item.getKey()),
        new Label(inner.getDate().toString()),
        new Label(new Label(String.valueOf(inner.getValue())))
        ;
        final double newProgress = currentRow / totalEntries;
        final int r = currentRow;
        Platform.runLater(() ->
        wrapper.addRow(r, nds);
        progress.setProgress(newProgress);
        );
        currentRow++;





        ).start();





        share|improve this answer













        Nodes can be created in any thread, but you must not add them to a scene from a background thread. You shouldn't update properties of nodes in a scene from a background thread either.



        GridPane wrapper = new GridPane();
        ProgressBar progress = new ProgressBar();
        viewBox.getChildren().add(progress);
        viewBox.getChildren().add(wrapper);

        new Thread(() ->
        Collection<Map.Entry<String, List<Observation>>> entries = handler.get(from, to).entrySet();
        final double totalEntries = entries.size();
        int currentRow = 1;
        for(Map.Entry<String, List<Observation>> item : entries)
        if(item != null)
        for(Observation inner : item.getValue())
        if(inner != null)
        // Add the data for the datalist
        final Node nds = new Node
        new Label(item.getKey()),
        new Label(inner.getDate().toString()),
        new Label(new Label(String.valueOf(inner.getValue())))
        ;
        final double newProgress = currentRow / totalEntries;
        final int r = currentRow;
        Platform.runLater(() ->
        wrapper.addRow(r, nds);
        progress.setProgress(newProgress);
        );
        currentRow++;





        ).start();






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 14 '18 at 21:25









        fabianfabian

        52.1k115272




        52.1k115272



























            draft saved

            draft discarded
















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53300726%2fdisplay-progressbar-while-dynamically-loading-gridpane%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            這個網誌中的熱門文章

            How to read a connectionString WITH PROVIDER in .NET Core?

            Node.js Script on GitHub Pages or Amazon S3

            Museum of Modern and Contemporary Art of Trento and Rovereto