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.
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.