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:

  1. Create a JavaFX project – IntelliJ does this for you!
  2. Add Maven support – IntelliJ does this too!
  3. Include a module descriptor file
  4. 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:

  • Ask Intellij for a new project and select JavaFX
  • Name your project!
  • That’s it! You’ve got a simple project laid out with the classic Main, Controller and FXML files created.

Of course, it won’t work yet – but that’s the basic structure of a JavaFX application done.

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

  • Right-click the root of your project in the Project Viewer and select “Add Framework Support”
  • Select Maven as your framework
  • Name your project – here we’re using the standard reverse-DNS with com.edencoding
  • Click to load your changes into your project (don’t forget this!)

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.

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:

  • Go to Modules
  • Copy the module name from the Name text box

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.

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 ‘requiregraphics 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;

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>.

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.

  1. Create a JavaFX project
  2. Add Maven support
  3. Include a module descriptor file
  4. 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!