Will Hartung
Will Hartung

Reputation: 118641

Font selection and rendering with JavaFX

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);
        }
    }
}

Upvotes: 0

Views: 1117

Answers (1)

VGR
VGR

Reputation: 44338

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().

Upvotes: 4

Related Questions