Platinum Partner
java,tutorial

JavaFX in Spring Day 1 – Application Initialization

I spoke recently to the Spring Dallas User Group, which was a great audience, and in preparation for the talk I dusted off my Spring Framework skills (with a little help from Josh Long).  Even though Spring is primarily targeted at server-side applications, you can actually do quite a nice integration between the two technologies on the client.  In addition to the full talk (which you can find below), I will elaborate on some of the patterns for building Spring/JavaFX hybrid applications in this blog.

To demonstrate how you can structure your application in JavaFX, I am going to build out a full Customer Data application over a 3 day blog series.  For easy reference, you can flip to any of the blogs (as they are published) here:

And here is a small teaser shot of the application login page (the full source will be posted on GitHub on the 3rd day):

You may be thinking to yourself why you should bother learning (or applying) Spring Framework in your JavaFX applications.  I am sure there are plenty of good use cases that I haven’t even thought of, but here were some of my motivations:

  • Modularizing the UI – Complicated JavaFX applications have many screens involved in the workflow, and it can be difficult to create a consistent structure for the pageflow of the application.  By taking advantage of Spring configuration and some age-old MVC patterns, you can greatly simplify this making it easy for others who maintain your application (maybe even yourself in 6 months time) to easily follow the structure.
  • Authentication and Authorization – No need to reinvent the wheel for user authentication and authorization.  You can take advantage of Spring Security, the most widely used authentication system in the Java ecosystem, to also handle permissions for your JavaFX application.
  • Dependency Injection – If you have UI classes with a ballooning number number of constructor parameters or mandatory setter methods, then dependency injection can help you to manage the chaos.  By taking advantage of Spring Bean dependencies and autowiring, you can have access to the model, controller, and other screens simply by declaring the relationships.

To start out with, let’s cover the “safe” way to integrate Spring Framework into your application.  Since you are not running in an application server environment, you need to manually bootstrap Spring, while also starting the JavaFX runtime.  Also, the same restrictions about making UI changes on the JavaFX Application thread apply to Spring code injected into your application, so to be safe you should always execute your code on the UI thread.

The following JavaFX Application main class meets all of these criteria:

public class CustomerApp extends Application {
    public static void main(String[] args) {
        launch(args);
    }
 
    @Override
    public void start(Stage stage) throws Exception {
        ApplicationContext context = new AnnotationConfigApplicationContext(CustomerAppConfiguration.class);
        ScreensConfiguration screens = context.getBean(ScreensConfiguration.class);
        screens.setPrimaryStage(stage);
        screens.loginDialog().show();
    }
}

In this example I am using annotation-based config for Spring.  This is my favorite way to write Spring applications for obvious reasons (and if you agree, please take a moment to sign my Freedom from XML Petition).

It is important to start the AnnotationConfigApplicationContext inside of the start method, because this runs all the Spring initialization on the UI thread.  While it is possible (and possibly desirable) to run the Spring startup in a separate thread, if you happen to create a new Stage, Pop-up, or modify the Scene Graph in any small way, you will get exceptions, deadlocks, or worse!  I highly recommend starting with this approach, and then selectively moving long-running operations onto worker threads if startup performance becomes an issue.

Notice that the “Bean” that we are loading from the configuration is not actually a Bean, but a special ScreensConfiguration class that contains all the UI beans.  This is a standard trick to allow lazy loading of Spring beans using Java Configuration (annotations), while letting you inject and access the beans directly.  It isn’t until we call screens.loginDialog() that the UI class will actually be instantiated.

This should be enough to get you started in initializing the Spring context in your own applications.  (In my Dallas UG talk I showed a simple media example configured entirely via Spring…  a good experiment to try yourself.)  In tomorrow’s blog I will go into detail on the ScreensConfiguration class as well as share some tricks for modularizing your UI and doing dependency injection into FXML controllers.

Until then, enjoy the presentation deck from the Dallas Spring User Group:

Published at DZone with permission of {{ articles[0].authors[0].realName }}, DZone MVB. (source)

Opinions expressed by DZone contributors are their own.

{{ tag }}, {{tag}},

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}
{{ parent.authors[0].realName || parent.author}}

{{ parent.authors[0].tagline || parent.tagline }}

{{ parent.views }} ViewsClicks
Tweet

{{parent.nComments}}