title: JavaFx Updating/Load new FXML GUI from Background Thread
body: <p>I am trying to update my UI thread which is displaying a Game. The background thread has to run the whole game because it is connected to a server and has to poll information from the server the whole time. I already tried with platform.runlater, task and service but I seem to be doing something badly wrong. Usually the background doesn't know the data from the application thread so I get either IllegalMonitorStateExceptions or NullPointerExceptions for the "rootLayout" BorderPane. Here is the rough structure of what I am trying to do.
  First I create an object of the class GUI and then I call the method "startApplication()".
  Thanks for your help.</p>
  
  <pre><code>  public class GUI extends Controller implements Runnable {
  
           public GUI(String ip, int port, String name) throws IOException {
                      super(ip, port, name);
                      this.name = name;
                      this.runs = false;
  
                      // Pass model and this class to the view class App
                      application = new App();
                      application.gainAccess(model, this);`
                      }
  
                      public void startApplication() {
                           application.main(null);
                      }   
  
                      public void run () {
                           //Calculations in Background Thread
                           Platform.runLater(new Runnable() {
                               @Override public void run() {
                                  application.showMainWindow();
  
                               }
                          });
                           //more Calculations
                      }
  
              }
  }
  
  
  public class App extends Application implements Runnable {
      public static void main(String[] args) {
          launch(args); // calls start(primaryStage)
      }    
  
      public void start(Stage primaryStage) throws Exception {
          System.out.println("start: " + gui);
  
          this.primaryStage = primaryStage;
          this.primaryStage.setTitle("TicketToRide");
          primaryStage.setMaximized(true);
          this.initRootWindow();
  
          this.showLoadingScreen();
          primaryStage.setFullScreen(false);
      }
  
      private void showLoadingScreen() {
          try {
             FXMLLoader loader = new FXMLLoader();
             loader.setLocation(App.class.getResource("LoadingWindow.fxml"));
             AnchorPane loadingWindow = (AnchorPane) loader.load();
  
             rootLayout.setCenter(loadingWindow);
  
             // Give the controller access to this class and with that the model
            LoadingWindowController loadingController =                loader.getController();
            loadingController.setApp(this);
         } catch (IOException e) {
            e.printStackTrace();
         }
     }
  
     public void initRootWindow() {
      try {
          FXMLLoader loader = new FXMLLoader();
          loader.setLocation(App.class.getResource("RootWindow.fxml"));
          rootLayout = (BorderPane) loader.load();
  
          Scene scene = new Scene(rootLayout);
          primaryStage.setScene(scene);
          primaryStage.show();
  
          // Give the controller access to this class and with that the model
          RootWindowController rootController = loader.getController();
          rootController.setApp(this);    
      } catch (IOException e) {
          e.printStackTrace();
      }
   }
  
   public void showMainWindow() {
          try {
              FXMLLoader loader = new FXMLLoader();
              loader.setLocation(App.class.getResource("MainWindow.fxml"));
              AnchorPane mainWindow = (AnchorPane) loader.load();
  
              rootLayout.setCenter(mainWindow);
  
              // Give the controller access to this class and with that the model
              MainWindowController mainController = loader.getController();
              mainController.setApp(this);
             // mainController.drawMap();
          } catch (IOException e) {
              e.printStackTrace();
          }
      }
  
  
   }
  </code></pre>
  
  <p>For some reason "rootlayout" is null.</p>
  
  <p>StackTrace:</p>
  
  <pre><code>Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
      at gui.implemenation.App.initRootWindow(App.java:94)
      at gui.implemenation.App.showEndingWindow(App.java:193)
      at de.unisaarland.sopra.zugumzug.GUI$1.run(GUI.java:48)
      at com.sun.javafx.application.PlatformImpl.lambda$null$170(Unknown Source)
      at com.sun.javafx.application.PlatformImpl$$Lambda$50/12559810.run(Unknown Source)
      at java.security.AccessController.doPrivileged(Native Method)
      at com.sun.javafx.application.PlatformImpl.lambda$runLater$171(Unknown Source)
      at com.sun.javafx.application.PlatformImpl$$Lambda$49/2990725.run(Unknown Source)
      at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(Unknown Source)
      at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
      at com.sun.glass.ui.win.WinApplication.lambda$null$145(Unknown Source)
      at com.sun.glass.ui.win.WinApplication$$Lambda$38/12617740.run(Unknown Source)
      at java.lang.Thread.run(Unknown Source)
  </code></pre>