Monday, 10 September 2012

JavaFX Cleanly Closing an FXML Based Application

Whilst developing an FXML based JavaFX application for JavaOne I had to overcome the problem of cleaning up Java background threads running in the controller on a ExecutorService.

If you had chosen to use the builder patterns rather than FXML this is a fairly trivial task, as you are likely to have direct access to the controller from your main class which extends Application. However, when you use FXML you will more than likely be declaring your controller as follows:
 <VBox xmlns:fx="" fx:controller="com.jclarity.anim.memory.MemoryController"> ...  

When you launch the FXML you are likely to do something along the lines of:

 public void start(Stage stage) throws Exception {  
    Parent root = FXMLLoader.load(getClass().getResource("MemoryMainView.fxml"));  
    Scene scene = new Scene(root, 600, 500);  
    stage.setTitle("JavaFX Memory Visualizer");;  

At this stage you launch the FXML and never grabbed hold of your reference to the controller. This now means when you override stop() you can't delegate this to your controller. The solution I found to this was to separate out the code above to ensure that you keep access to the FXML loader. If you have access to the FXMLoader you easily do the following in the stop method:
   public void stop() {  
     ((MemoryController) fxmlLoader.getController()).haltSimulation();  

I separated the code as follows:
 private FXMLLoader fxmlLoader;  

   public void start(Stage stage) throws Exception {  
     URL location = getClass().getResource("MemoryMainView.fxml");  
     fxmlLoader = new FXMLLoader();  
     fxmlLoader.setBuilderFactory(new JavaFXBuilderFactory());  
     Parent root = (Parent) fxmlLoader.load(location.openStream()); 

No comments:

Post a Comment