Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. Java
  4. JavaFX multithreading operation changing GUI elements

JavaFX multithreading operation changing GUI elements

Scheduled Pinned Locked Moved Java
helpquestionannouncement
6 Posts 3 Posters 1 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Offline
    J Offline
    JohnCodding
    wrote on last edited by
    #1

    I want to make it so that when the user launches the app, it will display the GUI but at the same time it will launch other threads (multithreading) that will do some calculations and when those are finished they will update some GUI elements (which are always created before the thread with calculations is launched, that is not a problem of getting null), also when a button is pressed same as before using multithreading it will do some calculation and update the GUI after each thread is done. Now the problem I have is that if you are using Thread(new Runnable)/start(); to launch multiple threads (even one) you get into the error Not on FX application thread. As possible solutions I read about JavaFX Task and Service but those were freezing the GUI thread until they were done. This is what I tried ("Functions.functionX" is the placeholder, the real function takes between 0-20 seconds to finish):

    					button.setOnAction(event -> {
    						Service doSomething = new Service() {
    							@Override
    							protected Task createTask() {
    								Functions.functionX("parameter");
    								return null;
    							}
    						};
    						doSomething.start();
    					});
    

    Now the problem with this is like I said, when the button is pressed, the GUI is unusable until the function finishes. Using straight Task had the same effect unfortunately. What do I need to change/add to make it so that I can launch multiple threads at a time, and inside them to change elements from GUI (right now I only want to update some Labels with .setText() inside those threads, each thread updates one Label)?

    J J 2 Replies Last reply
    0
    • J JohnCodding

      I want to make it so that when the user launches the app, it will display the GUI but at the same time it will launch other threads (multithreading) that will do some calculations and when those are finished they will update some GUI elements (which are always created before the thread with calculations is launched, that is not a problem of getting null), also when a button is pressed same as before using multithreading it will do some calculation and update the GUI after each thread is done. Now the problem I have is that if you are using Thread(new Runnable)/start(); to launch multiple threads (even one) you get into the error Not on FX application thread. As possible solutions I read about JavaFX Task and Service but those were freezing the GUI thread until they were done. This is what I tried ("Functions.functionX" is the placeholder, the real function takes between 0-20 seconds to finish):

      					button.setOnAction(event -> {
      						Service doSomething = new Service() {
      							@Override
      							protected Task createTask() {
      								Functions.functionX("parameter");
      								return null;
      							}
      						};
      						doSomething.start();
      					});
      

      Now the problem with this is like I said, when the button is pressed, the GUI is unusable until the function finishes. Using straight Task had the same effect unfortunately. What do I need to change/add to make it so that I can launch multiple threads at a time, and inside them to change elements from GUI (right now I only want to update some Labels with .setText() inside those threads, each thread updates one Label)?

      J Offline
      J Offline
      JudyL_MD
      wrote on last edited by
      #2

      Where do you get the "Not on FX application thread" error? When trying to launch all those threads or when you try to update the GUI from within one of those threads? If it's the former, I can't help. If it's the latter, you simply need to run your update code on the UI thread. I don't use JavaFX but in my Java / Android, this works fine.

      // called from a fragment
      Thread worker = new Thread (new Runnable ()
      {
      @Override public void run ()
      {
      // stuff to do not on the UI thread
      // ...

          // stuff is done, time to tell the UI
          activity.runOnUiThread (new Runnable ()
          {
              @Override public void run ()
              {
                  // code that touches the UI
              }
          });
      }
      

      });
      worker.start ();

      Be wary of strong drink. It can make you shoot at tax collectors - and miss. Lazarus Long, "Time Enough For Love" by Robert A. Heinlein

      V J 2 Replies Last reply
      0
      • J JudyL_MD

        Where do you get the "Not on FX application thread" error? When trying to launch all those threads or when you try to update the GUI from within one of those threads? If it's the former, I can't help. If it's the latter, you simply need to run your update code on the UI thread. I don't use JavaFX but in my Java / Android, this works fine.

        // called from a fragment
        Thread worker = new Thread (new Runnable ()
        {
        @Override public void run ()
        {
        // stuff to do not on the UI thread
        // ...

            // stuff is done, time to tell the UI
            activity.runOnUiThread (new Runnable ()
            {
                @Override public void run ()
                {
                    // code that touches the UI
                }
            });
        }
        

        });
        worker.start ();

        Be wary of strong drink. It can make you shoot at tax collectors - and miss. Lazarus Long, "Time Enough For Love" by Robert A. Heinlein

        V Offline
        V Offline
        Valentinor
        wrote on last edited by
        #3

        I get the error when I'm calling .setText(). Everything related to the GUI must run on FX thread, but if you are running something on that thread, well until it is finished the interface is frozen.

        1 Reply Last reply
        0
        • J JudyL_MD

          Where do you get the "Not on FX application thread" error? When trying to launch all those threads or when you try to update the GUI from within one of those threads? If it's the former, I can't help. If it's the latter, you simply need to run your update code on the UI thread. I don't use JavaFX but in my Java / Android, this works fine.

          // called from a fragment
          Thread worker = new Thread (new Runnable ()
          {
          @Override public void run ()
          {
          // stuff to do not on the UI thread
          // ...

              // stuff is done, time to tell the UI
              activity.runOnUiThread (new Runnable ()
              {
                  @Override public void run ()
                  {
                      // code that touches the UI
                  }
              });
          }
          

          });
          worker.start ();

          Be wary of strong drink. It can make you shoot at tax collectors - and miss. Lazarus Long, "Time Enough For Love" by Robert A. Heinlein

          J Offline
          J Offline
          JohnCodding
          wrote on last edited by
          #4

          I get the error when I call .setText(). Everything related to the GUI must run on FX thread, but if you are running something intensive on that, then the interface will freeze, that is why you should run that on a different thread and make the updates later.

          J 1 Reply Last reply
          0
          • J JohnCodding

            I want to make it so that when the user launches the app, it will display the GUI but at the same time it will launch other threads (multithreading) that will do some calculations and when those are finished they will update some GUI elements (which are always created before the thread with calculations is launched, that is not a problem of getting null), also when a button is pressed same as before using multithreading it will do some calculation and update the GUI after each thread is done. Now the problem I have is that if you are using Thread(new Runnable)/start(); to launch multiple threads (even one) you get into the error Not on FX application thread. As possible solutions I read about JavaFX Task and Service but those were freezing the GUI thread until they were done. This is what I tried ("Functions.functionX" is the placeholder, the real function takes between 0-20 seconds to finish):

            					button.setOnAction(event -> {
            						Service doSomething = new Service() {
            							@Override
            							protected Task createTask() {
            								Functions.functionX("parameter");
            								return null;
            							}
            						};
            						doSomething.start();
            					});
            

            Now the problem with this is like I said, when the button is pressed, the GUI is unusable until the function finishes. Using straight Task had the same effect unfortunately. What do I need to change/add to make it so that I can launch multiple threads at a time, and inside them to change elements from GUI (right now I only want to update some Labels with .setText() inside those threads, each thread updates one Label)?

            J Offline
            J Offline
            JohnCodding
            wrote on last edited by
            #5

            I managed to make it work but not with Task or Service. On button action I created a new Thread thread = new Thread(new Runnable() {...});, and after I was done with the calculation, still inside thread run function I called:

            		Platform.runLater(new Runnable() {
            			@Override
            			public void run() {
            				label.setText(newValue);
            			}
            		});
            

            I am still interested what I should do to make it work with those too, if someone can explain what I was doing wrong.

            1 Reply Last reply
            0
            • J JohnCodding

              I get the error when I call .setText(). Everything related to the GUI must run on FX thread, but if you are running something intensive on that, then the interface will freeze, that is why you should run that on a different thread and make the updates later.

              J Offline
              J Offline
              JudyL_MD
              wrote on last edited by
              #6

              And that is exactly what my code does. It creates the thread worker from the UI thread and starts it. It then exits that UI function, effectively releasing the UI thread. Meanwhile, worker is executing its Run method separately from the UI. After it finishes doing stuff, worker then creates and runs a UI thread that updates the UI. JavaFX may have a different method to call instead of runOnUiThread, but the logic is the same. JavaFX has to have an equivalent. Don't be confused by the code appearing to all be in the initial UI function. Each of those Run methods is a chunk of code that executes in a separate and distinct thread. One caveat -- when running on Android, I have found that this doesn't always work to release the UI when it is done from within view creation / fragment startup. I don't know if JavaFX has the same issue. What I've shown works when launched from the UI once the screen is up and established; for example, from a menu item click handler.

              Be wary of strong drink. It can make you shoot at tax collectors - and miss. Lazarus Long, "Time Enough For Love" by Robert A. Heinlein

              1 Reply Last reply
              0
              Reply
              • Reply as topic
              Log in to reply
              • Oldest to Newest
              • Newest to Oldest
              • Most Votes


              • Login

              • Don't have an account? Register

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • World
              • Users
              • Groups