if there’s one thing that can skyrocket your application from development to production-class it’s properly managed dependencies.
And the great news is it’s super-easy. We’ve even made a starter-application if you want the code. Just head to our GitHub and choose the SimpleMavenApplication.
Basic Steps To Using Maven
It really is amazingly easy to make a JavaFX project with Maven support in IntelliJ. In fact, you just have to do 4 simple things:
- Create a JavaFX project – IntelliJ does this for you!
- Add Maven support – IntelliJ does this too!
- Include a module descriptor file
- Add in some JavaFX dependencies
We’ve scattered optional hints and tips throughout the article. If you just need to get the project done, skip through and come back later. But the hints and tips really help later down the line when something goes wrong and you need to debug.
So by the end, you’ll understand what dependency management you’ve added. And, when you come to debugging, you’ll know what to do!
OK, let’s dive in! We’ll go through the 4 steps one by one.
1. Create a simple JavaFX project
There are only two steps to asking IntelliJ to give you a JavaFX project:

Of course, it won’t work yet – but that’s the basic structure of a JavaFX application done.
The JavaFX application itself mimics to a certain extent the HTML/JavaScript/CSS web framework. It’s based on the Model-View-Controller paradigm, with the FXML file fulfilling the View part. The Controller…well…that’s the controller part…
As the developer, you’re responsible for developing the models (the data structures) that fill the UI with information.
Here’s each part with quick description of what each file does:
File | Web-equivalent | Function |
---|---|---|
sample.fxml | HTML | Initial state of the application. The view. Bare bones of the UI. Unlike in HTML, in JavaFX it does have default styling |
Controller.java | JavaScript | Controls the environment, adding functionality to the elements defined in the FXML file. Can also be used to add custom elements, although this is a little less clean. |
CSS | CSS | JavaFX UI elements are all skinnable by CSS. All JavaFX styles are prefixed with “-fx-” to allow standard and JavaFX styles to be stored in the same file. |
.
2. Setting Up Maven
IntelliJ makes adding Maven to a project incredibly simple. It’s 4 clicks to add Maven and then a few lines of XML code to set up your project at the right language level. We’ll do each in turn.
a. Adding Maven

b. Setting the language level
Setting the language level for your project is incredibly important.Fortunately, it’s also dead simple. Five lines of code – that’s all you need. Without it, IntelliJ will default to language level 5 – so no lambdas and no modules!
To modify the language level we’ll start tinkering with Maven’s Project Object Model. It’s an XML file that helps Maven describe your project, its’ properties, dependencies and extra features.
Setting the Java language version
To use modules in our program we’ll need at least a language level 9. This is actually a build property of the program, so we dive into the pom.xml and set this under the <build>
element. We’ll configure the build element of the Maven compiler to a new language level.
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>9</source> <target>9</target> </configuration> </plugin> </plugins> </build>
IntelliJ will read this file and set the language level for our project, even when we’re not running a compile or build through Maven.
Next we’ll need to describe the modules we’ll include in the project, and then we’ll add JavaFX.
There’s a huge temptation to start adding Maven’s build plugins now. In fact, every tutorial out there bundles them into one tutorial.
Don’t do it.
In general, that’s just too much information to take in all at once. Unless you’ve got previous experience with Maven, you won’t understand why you’re adding them, or what they contribute to your project.
Get your app running in your IDE first, get it to a decent state where you want to worry about deployment, and then worry about deployment.
Let’s get your app running first.
3. Add a module descriptor
As of Java 9, modules have been included in the JDK to decrease the size of your application. They’re absolutely brilliant and if you haven’t started to convert your projects over to being modularised, now’s a great time to start.
The file that underpins the module strategy for every JAR we build from this point out will be the module-info.java file.
Create your module-info.java, and add some simple syntax:
module SimpleMavenApplication { }
The only thing to remember with this is that the module name should be exactly the same as the Project’s module name. To find that, go to File
-> Project Structure
or press Ctrl + Alt + Shift + S
. Then:

In three steps, we’ll add JavaFX to the project, give JavaFX access to our project, so it can display our content, and export our module so that the JavaFX Application class can render our application.
a. Adding JavaFX to our project
For every module we’re going to use, we need to add a ‘requires‘ statement. But we don’t need to add every JavaFX module.
JavaFX has a lot of modules. We only need four to run a basic user interface, although we can add more as needed. If you’re interested in all of them, there’s a drop-down below.
JavaFX has 6 modules. Not only do they each have different functions, but they also have dependencies between each other. For example, every module requires javafx.base. It’s the common JavaFX classes that every JavaFX program will need.
We’ll quickly go through each in turn, and then look at the dependencies that exist between JavaFX modules.
1. Base
Contains the simplest JavaFX constituent classes, such as Bindings, Properties, Collections, Events and some basic Util classes.
1. Graphics
This Defines the core scenegraph APIs for the JavaFX UI toolkit. It contains the classes for rendering, image handling, transition and transformation effects.
It also has more general classes for animation, css, geometry and windowing.
2. Swing
If you need Swing/JavaFX interoperability, this is the dependency you’ll need. It defines the SwingNode to allow you to include Swing components in JavaFX, and the JFXPanel, to include JavaFX nodes in Swing apps.
3. Controls
This set of classes defines all the UI controls. That’s generally anything the user can change, like buttons, boxes and fields.
It also includes Charts, which the user can also interact with, as well as the code for skinning all of these parts with css.
4. Media
JavaFX has a comprehensive support for media playing – both video and audio. You’ll need these classes for that purpose.
5. Web
Quite a small module, this includes support for displaying HTML content within a JavaFX application, editing HTML content, and handling web events like button clicks.
Dependencies of each JavaFX Module
As we mentioned above, each of the more complex modules depends on a number of ‘lower’ modules. here’s a full list:
Module | Requires |
---|---|
javafx.base | – |
javafx.graphics | javafx.base |
javafx.swing | javafx.graphics |
javafx.controls | javafx.graphics javafx.base |
javafx.fxml | javafx.graphics javafx.base |
javafx.media | javafx.graphics javafx.base |
javafx.web | javafx.base javafx.controls javafx.graphics |
For a simple JavaFX project, you’ll need base, graphics, fxml and controls modules.
module SimpleMavenApplication { requires javafx.controls; requires javafx.fxml; }
You’ll notice we’ve only added two… That’s because the controls and fxml modules already ‘require‘ graphics and base, so we don’t need to add them!
It’s actually a special type of requires statement, called requires transitive, which means you get access to the base and graphics modules too, without having to declare it.
Maven works that out for you and imports them as well.
b. Giving JavaFX access to our project
We’ll use the FXMLLoader to load our controllers into the UI. For that reason, we also need to make sure the JavaFX’s fxml module can access our controllers, so we will add one line beneath the requires statements.
opens com.edencoding to javafx.fxml;
As your program gets more complicated, you’re probably going to move your Controllers into a separate directory / package. At that point, you’ll want to update the opens statement to open the new package to javafx.fxml.
For example, if we’ve moved them to a new folder called “controllers”, we’ll use:
opens com.edencoding to javafx.fxml;
c. Exporting our module
The last line in our module-info.java will ensure that the graphics portion of JavaFX can access our application. That’s needed because our application extends JavaFX’s Application class, which is involved in the scene graph of the application. Without it, our application won’t run. So, we add as the last line:
exports com.edencoding;
4. Add JavaFX as a dependency within Maven
Now we’ve added the requires statements within our project, we’ll add the dependencies to the pom.xml so our dependencies will be downloaded automatically.
First, we’ll define the version of JavaFX we’re using, because all JavaFX modules use the same naming convention, and then we’ll add the Controls and FXML modules.
a. Setting the JavaFX version
The JavaFX version is a property of the project, so we’ll add an element inside the <properties>
tag in the newly-created pom.xml. This won’t do anything now, but it’ll be really useful later on when we add the JavaFX dependencies.
<properties> <javafx.version>13</javafx.version> </properties>
For every dependency, we’ll add the GroupID, ArtefactId and Version inside the <dependency>
element for that module.
All dependencies are included within the global <dependencies>
tag. Each separate dependency then has its own tag: <dependency>
.
Every dependency needs three things:
- GroupId
- ArtefactId
- Version. #
These allow Maven to unambiguously identify a dependency (known as an artefact) within the central repository.
All of our At some point you might want to change your dependencies as support for the version you’re using is stopped. That will probably involve some pretty heavy functional testing, but here’s what to do anyway.
What they mean, and how to change them:
GroupId
A Group ID defines who controls the artefact. It’s similar to the reverse-DNS we use for our project here (com.edencoding), which defines who owns the project.
All of the JavaFX artefacts we’re using are from OpenJFX, a well-supported project for JavaFX development.
Their Group ID is org.openjfx.
If you want to migrate your project later to another version of JavaFX, you may need to change the Group ID, but don’t forget to change the ArtefactID and Version to something suitable as well!
ArtefactId
Within every Group ID is every artefact that the group controls. In this case, it’s all the JavaFX modules plus some plugins that we’ll explore in other projects.
You can see all of the artefacts for org.openjfx here.
Later in your project, you may want to add more JavaFX dependencies. Check our the link above to see all the modules at the Maven Central Repository.
Version
Versions are often under-rated, but they can be critically important to maintaining code. Major versions usually come with extra functionality, but by convention lose at least some compatibility with previous major versions. So, choosing a version can be difficult.
The benefit of using a safe repository like Maven Central is that all the versions of an artefact are hosted indefinitely, which means you’ll never lose access to them.
If you need to update your version at some point in the future, check out the available versions for each artefact. Here they are for javafx.controls.
b. Adding Controls
OpenJFX make version control easy by synchronising their versions across modules. In this case, we defined the JavaFX version as a property higher up in the pom.xml file, so we define the dependency for controls as so:
<dependency> <groupId>org.openjfx</groupId> <artifactId>javafx-controls</artifactId> <version>${javafx.version}</version> </dependency>
c. Adding FXML
Adding support for FXML is just as simple and requires one more dependency:
<dependency> <groupId>org.openjfx</groupId> <artifactId>javafx-fxml</artifactId> <version>${javafx.version}</version> </dependency>
Fixing Lost Resources
When you add Maven framework support to the project, IntelliJ will add a resources root for you. For simple applications, that can seem like over-kill but it’s really good practice as applications grow in size.
It also allows your to define separate resources for test and source files, which will be really useful as you come to test the code.
Unfortunately for our quick project, that means that as you come to run your project, you’ll be hit with an InvocationTargetException
with a message that “Location is required”.
The long and the short of it is that the FXMLLoader can’t find your fxml file!
To fix that, let’s just quickly move the sample.fxml file into the resources folder and make one change to our code.
Moving sample.fxml

Updating our location code:
In our Main.java file, we currently use the static FXMLLoader method load() to bring in our FXML file.
FXMLLoader.load(getClass().getResource("sample.fxml"));
All we have to do is change that to “/sample.fxml”, which defines that rather than searching relative to our class, we want to find the resource relative to the content root (i.e. the resources folder!)
Now, our code should run. It won’t be particularly impressive, but it’ll run!
Conclusions
Adding Maven support to a project is really easy. We’ve taken a look in turn at doing it in 4 easy steps.
- Create a JavaFX project
- Add Maven support
- Include a module descriptor file
- Add in some JavaFX dependencies
We added some handy debug-aids and tips, which you might find useful down the line, so don’t forget to bookmark and save for later!