How do I use fallback fonts in JavaFX?

Viewed 591

For a project I am currently working on in JavaFX, I want the user to be able to enter a name of a Deck which can contain multiple languages (e.g. 日本語 N4 Vocab).

To be able to display fonts from multiple languages correctly, I tried specifying multiple fonts in the css of a textfield like this in a stack:

.text-field {
    -fx-font-family: "Work Sans", "Noto Sans JP";
}

But I realised that JavaFX does not support comma-separated series of font family names in the -fx-font-family property.

So I have a few questions:

  1. Is using fallback fonts as above the correct way to support using multiple fonts for a Label / TextField?
  2. If it is, how do I go around this limitation to implement this feature.
  3. If not, what else should I do to improve the rendering of multi-language Strings in JavaFX?

Update | This is what I tried:

@font-face {
    src: url('WorkSans-Regular.ttf');
}

@font-face {
    src: url('WorkSans-Bold.ttf');
}

@font-face {
    src: url('NotoSans-Regular.ttf');
}

.text-area {
    -fx-font-size: 30;
    -fx-font-family: 'Work Sans';
    -fx-font-weight: bold;
}

And this is the what the TextArea displays when unsupported characters are entered:

TextArea with unsupported characters

1 Answers

From the JavaFX CSS reference:

JavaFX CSS does not support comma-separated series of font family names in the -fx-font-family property. The optional line height parameter when specifying fonts is not supported. There is no equivalent for the font-variant property.

Possible workarounds:

  1. In your CSS: you can define and use multiple fonts with @font-face.
@font-face {
  src: url("../fonts/Roboto-Medium.ttf");
}
    
.my-text {
  -fx-font-family: roboto;
}

  1. In your code: you can check/use Font.loadFont() or Font.font().

Update: font-face code added

My demo code:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.TextArea;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class HelloFX extends Application {

    @Override
    public void start(Stage stage) {
        TextArea ta = new TextArea();

        VBox vbox = new VBox(ta);
        Scene scene = new Scene(vbox, 640, 480);
        scene.getStylesheets().add("style.css");
        stage.setScene(scene);
        stage.setTitle("JavaFX App");
        stage.show();

    }

    public static void main(String[] args) {
        launch();
    }
}

style.css

@font-face {
    src: url("fonts/WorkSans-Regular.ttf");
}

@font-face {
    src: url("fonts/NotoSans-Regular.ttf");
}

.text-area {
    -fx-font-size: 30;
    -fx-font-family: 'Work Sans';
    -fx-font-weight: bold;
}

My screenshot on macOS Mojave:

enter image description here

Maybe you don't have the fonts of different languages in your OS. Try to install the fonts in your OS.

Update 2: Demo code added.

Related