Home > Blockchain >  Cannot use custom font in javaFX using CSS Styling
Cannot use custom font in javaFX using CSS Styling

Time:01-13

I'm trying to add a Global font to my javaFX application using CSS. I followed this answer, however I can't seem to load the font, and the error message is not helpful.

jan 12, 2022 12:24:25 PM javafx.css.CssParser reportException
WARNING: Please report java.lang.NullPointerException at:

The error messages finishes here, not showing where the problem is.

My code directory: pacman directory

My main.java:

package finalPacman;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;


public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception{
        FXMLLoader loader = new FXMLLoader(getClass().getResource("pacman.fxml"));
        Parent root = loader.load();
        primaryStage.setTitle("PacMan");
        Controller controller = loader.getController();
        root.setOnKeyPressed(controller);
        double sceneWidth = controller.getBoardWidth()   20.0;
        double sceneHeight = controller.getBoardHeight()   100.0;
        Scene scene = new Scene(root, sceneWidth, sceneHeight);
        scene.getStylesheets().clear();
        scene.getStylesheets().add(getClass().getResource("pacman.css").toExternalForm());
        primaryStage.setScene(scene);
        primaryStage.show();
        root.requestFocus();
    }

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

My pacman.css:

@font-face {
    font-family: 'Pixeboy';
    src: url("/src/res/fonts/Pixeboy.ttf");
}

.root{
    -fx-font-size: 16;
    -fx-font-family: "Pixeboy";
}

CodePudding user response:

I found a way to solve this.

I changed my css file in order to remove @font-face

.root{
    -fx-font-size: 16;
    -fx-font-family: "Pixeboy";
}

The font family name should be the same as the file name without the '.tff'.

And loaded the font directly in my main.java:

package finalPacman;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.text.Font;
import javafx.stage.Stage;


public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception{
        FXMLLoader loader = new FXMLLoader(getClass().getResource("pacman.fxml"));
        Parent root = loader.load();
        primaryStage.setTitle("PacMan");
        Controller controller = loader.getController();
        root.setOnKeyPressed(controller);
        double sceneWidth = controller.getBoardWidth()   20.0;
        double sceneHeight = controller.getBoardHeight()   100.0;
        Scene scene = new Scene(root, sceneWidth, sceneHeight);
        Font.loadFont(getClass().getResourceAsStream("fonts/Pixeboy.ttf"), 16);
        scene.getStylesheets().add(getClass().getResource("pacman.css").toExternalForm());
        primaryStage.setScene(scene);
        primaryStage.show();
        root.requestFocus();
    }

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

CodePudding user response:

@font-face can work BUT:

  1. It needs to be first in your CSS file.

  2. It cannot use a leading slash in the src URL.

  3. The src URL must locate either

    • a web font via a valid full URL, e.g. http:, https: or file: protocols OR
    • to get it as a resource, it must be a relative path to the CSS file containing the @font-face directive.

If that is all set up correctly, then the instructions in the following answer work fine (verified with JavaFX 17):

An example URL that would work for the resources defined in the question is a src URL relative to the CSS file:

src: url("fonts/Pixeboy.ttf"); 

assuming that the font is actually located at that relative position to the CSS file referencing the @font-face.

When I tested, I used the CSS and fonts linked from the answer above.

Troubleshooting

  1. If you use a leading slash in the src URL for @font-face (for example src: url("/fonts/Pixeboy.ttf");), you will get the following message and the font will not be loaded:

    Jan 12, 2022 2:31:09 PM javafx.css.CssParser reportException
    WARNING: Please report java.lang.NullPointerException at:
    

    The error message will be generated and the font will not load even if the path is correct to locate the font file from the root of the class/module path.

  2. If you specify a location for the font which does not exist (for example src: url("wrongfoldername/Pixeboy.ttf");, you will get the following error message and the font will not load:

    Jan 12, 2022 2:43:18 PM com.sun.javafx.css.StyleManager loadStylesheetUnPrivileged
    INFO: Could not load @font-face font [file:/<build-output-dir>/wrongfoldername/Pixeboy.ttf]
    
  •  Tags:  
  • Related