Search code examples
multithreadingjavafxshared-variable

javafx call controller function from another thread


The question of the day is: how to call controllers function from another thread. My application looks like this:

public class Server {
//(...)
    public String setMsg(String string) {
       msg.set(string+"\n");
       mainScreenController.updateLog();
    }
//(...)
   while (true){
   doThings();
   }
}

    public class MainScreenController {
//(...)
    public void startServer(){
    new Thread(server::start).start();
    }
     public void updateLog(){
            Platform.runLater(()->{ testAreaLog.setText(testAreaLog.getText() + server.getMsg()); });
        }
//(...)
    }

I want to call updateLog() in the finally block, so every time server updates msg GUI adds this message to log window. My msg is

private volatile AtomicReference<String> msg = new AtomicReference<String>();

it works when i call updateLog(); in startServer(), it displays the first message Starting server as you may guessed, but calling another updateLog(); there returns null so I wanted to call it directly after getMsg() is used.


Solution

  • It's not really clear why you can't just do

    public class MainScreenController {
        //(...)
    
        public void startServer(){
            new Thread(server::start).start();
        }
    
        public void updateLog(String message){
            Platform.runLater(()-> testAreaLog.appendText(message + "\n"));
        }
    
        //(...)
    }
    

    and

    public class Server {
    
       public void start() {
           while (true){
               doThings();
               String newMessage = ... ;
               mainScreenController.updateLog(newMessage);
               doMoreThings();
           }
       }
    
    }
    

    This assumes something in your while loop is a blocking (or time-consuming) call, so that you are not flooding the UI thread with too many Platform.runLater() calls.