How to use "Font Awesome" Icons in JavaFX

There are many advantages that come from using fonts for icons instead of graphics. You can easily change the size and the color or manipulate basic properties like rotation. To make it even better, you do not have to provide extra icons with different resolutions for monitors with a higher pixel density.

The Basics

First things first you will need to do is download Font Awesome. The download contains the fontawesome-webfont.ttf file, which you have to add to the resources folder of your project. In a standard maven project structure, this would be src/main/resources, preferably in a subdirectory:


src/main/resources/fa/fontawesome-webfont.ttf

Now we need to introduce the font in the application. You can do this either by loading the font within the application code:


InputStream font = App.class.getResourceAsStream("/fa/fontawesome-webfont.ttf");
Font fontAwesome = Font.loadFont(font, 10);

Or you can include the font directly in the css:


@font-face {
   font-family: 'FontAwesome';
   src: url('/fa/fontawesome-webfont.ttf');
}

How to use the font in programmatically created GUI

To use the font in a programmatically created GUI, you just have to set it on the desired element:


static final ICON_ANDROID = "\uf17b";
Label label = new Label(ICON_ANDROID); 
label.setFont(fontAwesome);

The only inconvenience is, that we have to keep the reference to the font across the application. A simple way to fix it, is to set the style information about the font with setStyle


label.setStyle("-fx-font-family: 'FontAwesome'");

Or to set the font family in css


.fa-label {
  -fx-font-family: 'FontAwesome';
}

In the above example, I created a .fa-label css class which can be used to apply the font on selected elements.

How to use the font in FXML

In order to use Font Awesome in FXML, we have to reference it through ResourceBundle. Using the font icon value directly on the FXML element will not work (e.x. <Label text="\uf13c" />) and it will throw an exception during the FXML processing.

First, we need to prepare and load a properties file with icon definitions. We can obtain the values for the icons from the original font-awesome.css file. To avoid conflicts with other resource bundles, I used fa prefix for the icon names.


fa.compass=\uf14e
fa.compress=\uf066
fa.connectdevelop=\uf20e
...

For convenience, we add this file in the same place inside the project structure as the fontawesome-webfont.ttf file:


src/main/resources/fa/fontawesome-webfont.ttf
src/main/resources/fa/fontawesome.properties

The only remaining task is to introduce the properties file to the application. This is easily done with ResourceBundle:


@Override
public void start(Stage stage) throws Exception {
  FXMLLoader loader = new FXMLLoader();
  loader.setResources(ResourceBundle.getBundle("fa.fontawesome"));
  // ... 
}

In the above example the ResourceBundle containing the icons was loaded in the Application#start method and is available to all controllers in the application.

Finally, to use the icons font in fxml, we simply need to use it in the same manner as an internationalized string:


<Label text="%fa.compass" />

Resources