0

I have a Swing program that has this little bit of code:

font = new Font(Font.SANS_SERIF, Font.PLAIN, 8);

It renders like this: enter image description here

I picked this because I wanted the simple font, and I wanted it "portable".

In JavaFX I have:

font = Font.font("SansSerif", 8);

I had hoped for a similar result, however I get: enter image description here

It looks to be bolded.

I have tried all of the JavaFX options, such as font = Font.font("SansSerif", FontWeight.NORMAL, 8).

I've tried the different weight: LIGHT, THIN, etc.

I've tried Helvetica directly. I've tried Ariel. They all look the same.

I wrote a simple sampler where you can select the Font name and see what you get. A lot of the fonts have different names, but don't change at all.

I ran through the Helveticas: Helvetica, Helvetica Bold, Helvetica Bold Oblique, Helvetica Light, Helvetica Light Oblique. They all look the same, none of them are bold, none of them are italic or light or anything. The names seem to make no difference whatsoever.

Some work, Monospace works, Times works -- as in they're not SansSerif/Helvetica.

Now, for JavaFX, I'm just doing:

Text t = new Text(x, y, text);
t.setFont(font);
getChildren.add(t);

I'm not use CSS for anything, not consciously. I have no CSS file.

So, I don't know why my font selections aren't working.

Here's the code to my Font selector experiment.

Clear I think I'm missing something fundamental with fonts and text in JavaFX.

public class App extends Application {
    @Override
    public void start(Stage stage) {
        FontControlPane pane = new FontControlPane();
        var scene = new Scene(pane, 640, 480);
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        launch();
    }
}
public class FontControlPane extends Pane {
    FontSizePane fsPane;
    ComboBox<String> comboBox;

    public FontControlPane() {
        fsPane = new FontSizePane();
        ObservableList<String> families = FXCollections.observableList(Font.getFontNames());
        comboBox = new ComboBox<>(families);
        comboBox.setOnAction(e -> fsPane.setFontName(comboBox.getValue()));
        populateMap();
    }

    private void populateMap() {
        ObservableList<Node> list = getChildren();
        list.clear();
        BorderPane pane = new BorderPane();
        pane.setTop(comboBox);
        pane.setCenter(fsPane);
        list.add(pane);
    }
}
public class FontSizePane extends Pane {
    String fontName;

    public FontSizePane() {
        this.fontName = fontName;
        populate();
    }

    public String getFontName() {
        return fontName;
    }

    public void setFontName(String fontName) {
        this.fontName = fontName;
        populate();
    }

    private void populate() {
        ObservableList<Node> list = getChildren();
        list.clear();
        setBackground(new Background(new BackgroundFill(Color.WHITE, CornerRadii.EMPTY, Insets.EMPTY)));
        if (fontName == null) {
            Text t = new Text(0, 20, "No font selected");
            list.add(t);
            return;
        }

        Set<Line> lines = new HashSet<>();

        Text t = new Text(0, 20, fontName);
        list.add(t);
        double y = 30;
        double x = 0;
        String text = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz 0123456789";
        for (int size = 4; size < 72; size += 4) {
            Font f = Font.font(fontName, size);
            t = new Text(x, y, text);
            t.setFont(f);
            list.add(t);

            y += (t.getLayoutBounds().getHeight() + 2);
        }
    }
}

1 Answer 1

4

JavaFX uses CSS generic font families. (On my Linux system, serif, sans-serif, and monospace work, but cursive and fantasy do not.)

There is no font named Ariel, as far as I know. Perhaps you meant Arial?

Helvetica will only work if that font is actually installed on your computer. Windows does not come with Helvetica by default, as far as I’m aware.

Update:

This line is incorrect:

ObservableList<String> families = FXCollections.observableList(Font.getFontNames());

The getFontNames method does not return valid families. For that, use Font.getFamilies().

Sign up to request clarification or add additional context in comments.

7 Comments

Thanks for the font reference. I tried 'sans-serif' for my Font, but it made no difference. Most of the others were from the list provided by the OS (macOS in my case). Clearly it falls back to some sans-serif font if it doesn't understand the font name, but in my example above, I'm iterating through the font names provided by the system (using Font.getFontNames()).
ObservableList<String> families = FXCollections.observableList(Font.getFontNames()); is incorrect, because getFontNames() does not return a list of families. Use Font.getFamilies() for that.
I think this answer is a bit misleading. The family handling in the javafx.scene.text.Font API is not well-documented, but it doesn't mention the usage of CSS generic font families and, at least on a Mac, doesn't appear to recognize them. I think the information on CSS generic font families only applies if the fonts are referenced in CSS rather than via the javafx.scene.text.Font API.
@jewelsea After more testing, I think you may be partially right. sans-serif does work, but SansSerif, which is returned by Font.getFamilies(), also works. Now I wish the generic names were better documented.
I looked through the code for the JavaFX CSS implementation to see if it has some kind of internal mapping of font-family names that are applied before calling font APIs, and it doesn't. So what is set in CSS is the same as what is applied to the Font.font(String family, FontWeight weight, FontPosture posture, double size) API call.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.