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().
Here is my main Application class where i load the fxml:
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();
}
So here are some parts of FXMLDocumentController:
public class FXMLDocumentController implements Initializable {
...
@FXML
private TableView<SystemMessage> systemMessages;
@FXML
private TableColumn<SystemMessage, DateTime> dateSysReceived;
@FXML
private TableColumn<SystemMessage, String> messageText;
@FXML
private TableColumn<SystemMessage, String> messageType;
...
private ObservableList<SystemMessage> 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<>("dateSysReceived"));
messageText.setCellValueFactory(new PropertyValueFactory<>("messageText"));
messageType.setCellValueFactory(new PropertyValueFactory<>("messageType"));
...
}
...
private ObservableList<SystemMessage> getAllMessages() {
ObservableList<SystemMessage> data = FXCollections.observableArrayList();
data = FXCollections.observableArrayList();
SystemMessageDAO msgDAO = new SystemMessageDAOImpl();
List<SystemMessage> allMessages = new ArrayList<>();
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)
}
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:
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();
}
}
- 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.
Above implementation is according to: Accessing FXML controller class however i am getting a:
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)
Hope my objective is clear and the approach above is not out of scope.