title: Call a javafx fxml controller method from another class to update a tableview
body: <p>I am trying to update a javafx tableview defined in my fxml controller by calling a particular method FXMLDocumentController.onAddSystemMessage() from another application utility class method GlobalConfig.addSystemMessage(). </p>
  
  <p>Here is my main Application class where i load the fxml:</p>
  
  <pre><code>public class Main extends Application {
      ...
      public static void main(String[] args) throws IOException {
          Application.launch(args);
      }
      ...
      @Override
      public void start(Stage primaryStage) throws IOException {
          AnchorPane page = (AnchorPane) FXMLLoader.load(Main.class.getResource("FXMLDocument.fxml"));
          Scene scene = new Scene(page, initWidth, initHeight);
          primaryStage.setScene(scene);
  
          currentPane(scene, page);
          primaryStage.show();
      }
  </code></pre>
  
  <p>So here are some parts of FXMLDocumentController:</p>
  
  <pre><code>public class FXMLDocumentController implements Initializable {
      ...
      @FXML
      private TableView&lt;SystemMessage&gt; systemMessages;
      @FXML
      private TableColumn&lt;SystemMessage, DateTime&gt; dateSysReceived;
      @FXML
      private TableColumn&lt;SystemMessage, String&gt; messageText;
      @FXML
      private TableColumn&lt;SystemMessage, String&gt; messageType;
      ...
      private ObservableList&lt;SystemMessage&gt; messagesData;
      ...
      private GlobalConfig globalConfig;
      ...
      @Override
      @FXML
      public void initialize(URL url, ResourceBundle rb) {
          config = new GlobalConfig();
          ...
          messagesData = FXCollections.observableArrayList();
          messagesData = getAllMessages();
          systemMessages.getItems().setAll(messagesData);
          dateSysReceived.setCellValueFactory(new PropertyValueFactory&lt;&gt;("dateSysReceived"));
          messageText.setCellValueFactory(new PropertyValueFactory&lt;&gt;("messageText"));
          messageType.setCellValueFactory(new PropertyValueFactory&lt;&gt;("messageType"));
      ...
      }
      ...
      private ObservableList&lt;SystemMessage&gt; getAllMessages() {
          ObservableList&lt;SystemMessage&gt; data = FXCollections.observableArrayList();
          data = FXCollections.observableArrayList();
  
          SystemMessageDAO msgDAO = new SystemMessageDAOImpl();
          List&lt;SystemMessage&gt; allMessages = new ArrayList&lt;&gt;();
          allMessages = msgDAO.listSystemMessage();
  
          for(SystemMessage msg: allMessages) {
              data.add(msg);
          }
  
          return data;
      }
      ... // and here is the method that i would like to call to add new record to tableview
  
      public void onAddSystemMessage(SystemMessage systemMessage) {
          log.info("Add System Message called!");
          // to DO ... add item to tableview
          //this method should be called when inserting new systemMessage (DAO)
      }
  </code></pre>
  
  <p>Here is also my utility class with a method for adding a system message to database. Additionally I would like to call FXMLDocumentController.onAddSystemMessage(...) method to update tableview with a new item:</p>
  
  <pre><code>public final class GlobalConfig {
      ...
      //constructor
      public GlobalConfig () {
          ...
      }
  
      public void addSystemMessage(String messageText, String messageType) {
  
          SystemMessage msg = new SystemMessage();
          DateTime cur = DateTime.now();
  
          try {
              msg.setDateSysReceived(cur);
              msg.setMessageText(messageText);
              msg.setMessageType(messageType);
              SystemMessageDAO msgDAO = new SystemMessageDAOImpl();
              msgDAO.addSystemMessage(msg);
  
              FXMLLoader loader = new FXMLLoader(getClass().getResource("FXMLDocumentController.fxml"));
              FXMLDocumentController controller = (FXMLDocumentController)loader.getController();
              //just call my Controller method and pass msg
              controller.onAddSystemMessage(msg);
  
  
          } catch (Exception e) {
              e.printStackTrace();
          }
      }
  </code></pre>
  
  <ul>
  <li>GlobalConfig is a utility class which have some methods for fetching parameters from db as also doing some jobs such as adding some new values to db tables. It is called from several parts of my application and i would like to grab current FXMLDocumentController object and call its method onAddSystemMessage() for updating UI.</li>
  </ul>
  
  <p>Above implementation is according to: <a href="https://stackoverflow.com/questions/10751271/accessing-fxml-controller-class">Accessing FXML controller class</a> however i am getting a:</p>
  
  <pre><code>java.lang.NullPointerException
  at com.npap.utils.GlobalConfig.addSystemMessage(GlobalConfig.java:85)
  at com.npap.dicomrouter.FXMLDocumentController.startDcmrcvService(FXMLDocumentController.java:928)
  at com.npap.dicomrouter.FXMLDocumentController.initialize(FXMLDocumentController.java:814)
  at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2548)
  at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441)
  at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3214)
  at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3175)
  at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3148)
  at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3124)
  at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3104)
  at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3097)
  at com.npap.dicomrouter.Main.start(Main.java:141)
  at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$163(LauncherImpl.java:863)
  at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$176(PlatformImpl.java:326)
  at com.sun.javafx.application.PlatformImpl.lambda$null$174(PlatformImpl.java:295)
  at java.security.AccessController.doPrivileged(Native Method)
  at com.sun.javafx.application.PlatformImpl.lambda$runLater$175(PlatformImpl.java:294)
  at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
  at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
  at com.sun.glass.ui.win.WinApplication.lambda$null$149(WinApplication.java:191)
  at java.lang.Thread.run(Thread.java:745)
  </code></pre>
  
  <p>Hope my objective is clear and the approach above is not out of scope. </p>