Can’t make changes to interface in a runnable with JavaFX

Tags: , , ,



In my program, I am running a separate script and I am using concurrency to run the separate script, and therefore using a class implementing Runnable.

When the the separate thread is running, I want there to be a different graphic to when the thread is not running so the user can see if something is happening after pressing the button.

The function of the thread is working fine, it is just that after the thread has finished, the button graphic does not change when I try to change the graphic from inside the thread.

Code related to the issue:

In the class:

        downloadSongs.setOnMousePressed(new EventHandler<MouseEvent>() {  
        @Override
        public void handle(MouseEvent event) { 
            
            try{
                if(dnld.isAlive()==true){
                    
                }else{
                    dnld = new Thread(new DownloadThread());
                    dnld.start();
                }
            }catch(Exception e){
                dnld = new Thread(new DownloadThread());
                dnld.start();
            }

In the thread:

public class DownloadThread implements Runnable{
    public void run(){
        *function of run which works*
        try {
             *more code*
            } catch (Exception e) {
                            ErrorPopUp.Display();
                            //add in the red line around it being added/taken away
                            Download.downloadSongs.setGraphic(Download.download);
        }
        Download.downloadSongs.setGraphic(Download.download);

Answer

You cannot change the user interface outside the application thread. All user interface code checks isFxApplicationThread() and throw an exception if not.

You either need to call runLater to ensure your update is executed on the application thread, or implement a Task

To learn more about concurrency in JavaFX you can check out the Concurrency in JavaFX trail.



Source: stackoverflow