How to integrate custom fonts in your JavaFX application by using CSS

#JavaFX

This is one of the CSS tips that were part of my “Extreme Guimaker” talk at JavaOne this year and will show how you can change the font for a complete application or only a specific control by using CSS.

Before explaining the CSS solution I want to show a short example in Java code:

Button b = new Button("Text");
b.setFont(new Font("Arial", 24));

In the code, the font of a button is set to “Arial” with a size of 24. All basic nodes in JavaFX that contains a text provide a font property that can be simply used to define a new font for the node. I don’t think that this is a best practice because the font is an attribute that styles the application and therefore it should be separated from the application code.

Set fonts by CSS

Fortunately JavaFX supports CSS and therefore we can extract the font specification from the Java code and add it to CSS. I won’t discuss how IDs and style classes in CSS work in this post (If you not familiar with CSS you should have a look in [my book]({{ site.baseurl }}{% link pages/mastering-javafx-controls.md %})). The font of a node can be defined by using the -fx-font-* attributes in CSS. You can find a documentation of these attributes here. Here is an example that defines the font for a button:

#my-button {
  -fx-font-family: "Arial";
  -fx-font-size: 24;
}

If you want to define a global font for all controls in your application you can simply set the font to the .text style class. The Text shape in JavaFX contains this pseudo class by default and all nodes that render a text on the screen use the Text shape internally. Here is the css rule that will set the font for a complete application:

.text {
    -fx-font-family: "Asap";
}

Adding custom fonts

In the examples “Arial” is used as the custom font. Normally you can assume that this font will be installed on a client system. But sometimes you want to use a custom font to create a unique UI. In the following example, I want to use the Roboto font that is the official font of Googles Material Design. Normally this font won’t be installed on a client system. So if you define the font by CSS and a customer will run the application without installing the specific font on the OS JavaFX will select a system font as a fallback and the cool UI of the app is broken. But thankfully there is a good solution for this problem. Since Java 8 JavaFX supports the @font-face rule that can be used to add fonts. As a first step, the font file must be added to the application. As a best practice the file should be added to the resources folder:

font

Once this is done the font can be defined in CSS by using the @font-face rule:

@font-face {
    font-family: 'Roboto';
    src: url('Roboto-Medium.ttf');
}

.text {
    -fx-font-family: "Roboto";
}

Now the font will be used in our application even if it isn’t installed on the OS:

font-loaded

Update

As I learned today the shown code isn’t working in Java versions >= 1.8u60. Starting with this version the attribute “font-family” is ignored and you have to use the real name of the TTF.

If you want to use the font “Birds of Paradis” that is contained in the file demo.ttf, for example, you have to use this CSS file:

@font-face {
  src: url(/ui/font/demo.ttf);
}

.label {
  -fx-font-family: Birds of Paradise;
}

Hendrik Ebbers

Hendrik Ebbers is the founder of Open Elements. He is a Java champion, a member of JSR expert groups and a JavaOne rockstar. Hendrik is a member of the Eclipse JakartaEE working group (WG) and the Eclipse Adoptium WG. In addition, Hendrik Ebbers is a member of the Board of Directors of the Eclipse Foundation.

Circle Circle
logo

Open Source made right

Privacy

Privacy Policy Cookie Policy Privacy Config Impressum