DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Authentication With Remote LDAP Server in Spring Web MVC
  • A Practical Guide to Creating a Spring Modulith Project
  • Distributed Tracing System (Spring Cloud Sleuth + OpenZipkin)
  • Using Kong Ingress Controller with Spring Boot Services

Trending

  • A Developer's Guide to Mastering Agentic AI: From Theory to Practice
  • Grafana Loki Fundamentals and Architecture
  • Ensuring Configuration Consistency Across Global Data Centers
  • Unlocking AI Coding Assistants Part 1: Real-World Use Cases
  1. DZone
  2. Coding
  3. Frameworks
  4. Tutorial: Reactive Spring Boot, Part 3: A JavaFX Spring Boot Application

Tutorial: Reactive Spring Boot, Part 3: A JavaFX Spring Boot Application

Learn more about building reactive Spring Boot applications with JavaFX.

By 
Trisha Gee user avatar
Trisha Gee
·
Nov. 19, 19 · Tutorial
Likes (10)
Comment
Save
Tweet
Share
21.3K Views

Join the DZone community and get the full member experience.

Join For Free

Circular architecture pattern

Learn more about building reactive Spring Boot applications with JavaFX.

This is the third part of our tutorial showing how to build a Reactive application using Spring Boot, Kotlin, Java, and JavaFX. The original inspiration was a 70-minute live demo.

This third demonstration shows how to create a JavaFX application that is launched and managed via Spring Boot so that we can use Spring features like Inversion of Control in our JavaFX application.

This blog post contains a video showing the process step-by-step and a textual walk-through (adapted from the transcript of the video) for those who prefer a written format.


This tutorial is a series of steps during which we will build a full Spring Boot application featuring a Kotlin back-end, a Java client, and a JavaFX user interface.

This step shows how to create a Spring Boot JavaFX application so that JavaFX can take advantage of Spring features like Dependency Injection.

Setting Up the Module

In the video, we re-use the client project we created for the previous step and add a new module to it. But if we wanted to create this as a standalone project, and we could create this as a new project rather than a new module, the steps would be very similar (replacing "new module" with "new project").

  1. With the stock-client project from the previous step open in IntelliJ IDEA, create a new module.
  2. This is a Spring Boot application, so choose Spring Initializr from the options on the left.
  3. We're using Java 13 as the SDK for this tutorial, although we're not using any of the Java 13 features (you can download JDK 13.0.1 here, then define a new IntelliJ IDEA SDK for it).
  4. Enter the group name for the project and call the artifact stock-ui.
  5. Keep the defaults of a Maven Project with Java and Jar packaging.
  6. We'll select Java 11 as the Java version as this is the most recent Long Term Support version for Java, but for the purposes of this project, it makes no difference.
  7. Enter a helpful description for the module. This is our third module, so it helps us to keep clear in our mind what each module is responsible for.
  8. We can optionally change the default package structure if we wish.
  9. We don't need to select any Spring Boot Starters for this module.
  10. Keep the default module name and location.

IntelliJ IDEA downloads the created project from Spring Initializr and sets up the IDE correctly. If we're given the option to "show run configurations in services", we can select this. The services window is a slightly nicer and more useful way to see our running services and can help us to manage microservice applications.

The Spring Boot Application Class

As usual, Spring Boot generated a default application class for us. We will need to change this in order to launch a JavaFX application, but for now, we'll just leave this as it is.

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class StockUiApplication {
    public static void main(String[] args) {
        SpringApplication.run(StockUiApplication.class, args);
    }
}


Updating the Spring Boot Settings

Since this is a JavaFX application and not a web application, add this to the application.properties file of this module:

spring.main.web-application-type=none


Create a JavaFX Application Class

  1. Create a new Java class in the same package as the Spring application class and call it ChartApplication.
  2. (Tip: You can use Alt+Insert for Windows/Linux (⌘N on macOS) in the project window to create a new file or directory).
  3. Have it extend javafx.application.Application.

This is not currently on the classpath since we haven't added JavaFX to our dependencies yet, so we need to add it to our pom.xml file.

  1. (Tip: Pressing Alt+Enter on the red Application text in the editor gives the option to "Add Maven Dependency".)
  2. Add org.openjfx:javafx-graphics as a dependency, version 13.
<dependency>
    <groupId>org.openjfx</groupId>
    <artifactId>javafx-graphics</artifactId>
    <version>13</version>
</dependency>


  1. Now import javafx.application.Application in ChartApplication.
  2. Application is an abstract class, so we need to override a method.
  3. (Tip: We can get IntelliJ IDEA to implement these methods by pressing Alt+Enter on the red error, selecting Implement methods, and choosing the methods to implement.)
  4. We only have one method we need to implement, start.
import javafx.application.Application;
import javafx.stage.Stage;

public class ChartApplication extends Application {
    @Override
    public void start(Stage stage) {

    }
}


Setting Up the Spring Boot Application Class

Now that we have a JavaFX application, we need to launch it from the Spring Boot application.

Instead of using SpringApplication to run the application, we'll use the JavaFX Application class and call launch with the class that is our JavaFX class, ChartApplication, and the application arguments.

import javafx.application.Application;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class StockUiApplication {
    public static void main(String[] args) {
        Application.launch(ChartApplication.class, args);
    }
}


The reason we need two separate application classes for our application is because of JavaFX and Java Modules, it's beyond the scope of this tutorial to go into the details. If we want to use JavaFX and Spring together but aren't going to use Java Modules from Java 9, this is one way to get it to work.

Publishing Events via the Application Context

Let's go back to our JavaFX application class, ChartApplication.

  1. Create a field applicationContext; this will be a ConfigurableApplicationContext.
  2. Our start method, which is a standard JavaFX method, is called with a Stage object when the stage is ready to be used. We can use the Spring pattern of publishing events via the application context to signal when this Stage is ready. Inside  start(), call applicationContext.publishEvent() with a new StageReadyEvent.
  3. Pass the stage into the event constructor.
public class ChartApplication extends Application {
    private ConfigurableApplicationContext applicationContext;

    @Override
    public void start(Stage stage) {
        applicationContext.publishEvent(new StageReadyEvent(stage));
    }
}


Now, we need to create our StageReadyEvent.

static class StageReadyEvent extends ApplicationEvent {
    public StageReadyEvent(Stage stage) {
        super(stage);
    }
}


  1. Create it as an inner class in ChartApplication for simplicity. It can always be refactored out at a later date.
  2. (Tip: Pressing Alt+Enter on the red StageReadyEvent offers the option to "Create inner class StageReadyEvent).
  3. In the StageReadyEvent constructor, pass the stage parameter into the super constructor.
  4. Make this inner class static and package visible, other classes will be listening for this event.

Creating the Application Context

There are some other useful methods in Application that we can override and make use of.

  1. Override the init() method. This is where we need to initialize our application context.
  2. (Tip: You can use Ctrl+O within a class to select superclass methods to override).
  3. Create a new SpringApplicationBuilder, and give it our Spring Boot application class, which is StockUiApplication.
  4. Callrun() to get the application context and assign it to the applicationContext field.
@Override
public void init() {
    applicationContext = new SpringApplicationBuilder(StockUiApplication.class).run();
}


Closing the Application Context

Since we have an init() method, we should probably have some sort of tear down or cleanup too.

  1. Override the Application's stop method.
  2. Inside  stop(), call applicationContext.close().
  3. Also call Platform.exit() to end the JavaFX program.
@Override
public void stop() {
    applicationContext.close();
    Platform.exit();
}


Now, we have our Spring Boot application class, which launches our JavaFX Application class, ChartApplication:

import javafx.application.Application;
import javafx.application.Platform;
import javafx.stage.Stage;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ConfigurableApplicationContext;

public class ChartApplication extends Application {
    private ConfigurableApplicationContext applicationContext;

    @Override
    public void init() {
        applicationContext = new SpringApplicationBuilder(StockUiApplication.class).run();
    }

    @Override
    public void start(Stage stage) {
        applicationContext.publishEvent(new StageReadyEvent(stage));
    }

    @Override
    public void stop() {
        applicationContext.close();
        Platform.exit();
    }

    static class StageReadyEvent extends ApplicationEvent {
        public StageReadyEvent(Stage stage) {
            super(stage);
        }
    }
}


Listening to Application Events

We need something which is going to listen to the StageReadyEvent that we created.

  1. Create a new class, StageInitializer. This will set up our JavaFX Stage when it's ready.
  2. This class should be annotated as a Spring@Component.
  3. This class needs to implement ApplicationListener, listening for our StageReadyEvent.
  4. We need to implement the method on this interface, onApplicationEvent.
  5. (Tip: IntelliJ IDEA can do this for us, press Alt+Enter on the red error and select "Implement methods").
  6. The onApplicationEvent takes a StageReadyEvent. Call getStage on the event and assign the result to a Stage local variable.
import javafx.application.Application;
import javafx.application.Platform;
import javafx.stage.Stage;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ConfigurableApplicationContext;

public class ChartApplication extends Application {
    private ConfigurableApplicationContext applicationContext;

    @Override
    public void init() {
        applicationContext = new SpringApplicationBuilder(StockUiApplication.class).run();
    }

    @Override
    public void start(Stage stage) {
        applicationContext.publishEvent(new StageReadyEvent(stage));
    }

    @Override
    public void stop() {
        applicationContext.close();
        Platform.exit();
    }

    static class StageReadyEvent extends ApplicationEvent {
        public StageReadyEvent(Stage stage) {
            super(stage);
        }
    }
}


(Note: This code will not compile yet)

This method doesn't exist, so we need to create it on StageReadyEvent.

  1. (Tip: We can get IntelliJ IDEA to create this for us by pressing Alt+Enter on the red getStage method name in StageInitializer and selecting "Create method getStage").
  2. The superclass has a method that does what we want, getSource. This returns an object, so call it and cast the returned value to a Stage.
static class StageReadyEvent extends ApplicationEvent {
    public StageReadyEvent(Stage stage) {
        super(stage);
    }

    public Stage getStage() {
        return ((Stage) getSource());
    }
}


We know the source is a Stage because when we passed our stage constructor parameter into the super constructor, this became the source.

Final Steps

The Stage is ready for us to set up our user interface. We can run our StockUIApplication and see it successfully start-up as a Spring Boot application. It does also launch a Java process that would show a UI if we had created one. For now, we have successfully created a JavaFX application that is launched and managed with Spring and allows us to use the convenient features of any Spring application.

The full code is available on GitHub.

Further Reading

Tutorial: Reactive Spring Boot, Part 2: A REST Client for Reactive Streams

Spring Framework application Spring Boot JavaFX intellij

Published at DZone with permission of Trisha Gee, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Authentication With Remote LDAP Server in Spring Web MVC
  • A Practical Guide to Creating a Spring Modulith Project
  • Distributed Tracing System (Spring Cloud Sleuth + OpenZipkin)
  • Using Kong Ingress Controller with Spring Boot Services

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!