javafxcanvasfontsmonospacegraphicscontext

I cannot get JavaFX GraphicsContext strokeText() to display monospaced fonts right


Question: I would like for the GraphicContext object to stroke the text in a monospaced font. How can this be achieved?

Problem: I am using JavaFX. I have a Canvas object and a GrahpicsContext object. I want to use GraphicsContext's strokeText() method to draw text on the canvas. Before I call strokeText(), I use GraphicsContext object's setFont() to set the font to a monospaced font. It is important that all the characters in the string that I want to draw on the canvas have the same width. I have tried drawing the text on the canvas with fonts Courier, Courier New and Monospace. I understood that these fonts are supposed to be monospaced. I have imported javafx.scene.text.Font.

However, when I check the text drawn on the canvas, I see this every time: Screenshot of the left corner of my canvas object.

To test the fonts I made the GraphicsContext object stoke 5 times characters '_', 'a', 'i', and 'W' each on their own row. The characters are not of equal size and the lines are of different length. Also, I don't see any change in the font.

Here is the code I use for creating the canvas, drawer and stroking the text:

Canvas canvas = new Canvas(800,200);
GraphicsContext drawer = canvas.getGraphicsContext2D();
drawer.setFill(Color.BLACK);
drawer.setFont(new Font("Monospaced",15));

drawer.strokeText("_____", 5, 5);
drawer.strokeText("aaaaa", 5, 25);
drawer.strokeText("iiiii", 5, 45);
drawer.strokeText("WWWWW", 5, 65);

I searched for information about monospaced fonts in java, tried importing java.awt.Fonts and looked through the javadoc of GraphicsContext but nothing seemed to help me with this problem.

What am I doing wrong?


Solution

  • new Font(String name, double size) creates a font based on the full name of the font and the font size. Font.font(String family, double size) creates a font based on the font family name and the font size.

    In your case the family name is "Monospaced" (java.awt.Font.MONOSPACED), the full name is "Monospaced Regular", and the file name on my Windows platform is C:\Windows\Fonts\cour.ttf (Courier New).

    I prefer

    drawer.setFont(Font.font("Monospaced", 15));
    

    but

    drawer.setFont(new Font("Monospaced Regular", 15));
    

    and

    drawer.setFont(Font.loadFont(Files.newInputStream(Paths.get("C:/Windows/Fonts/cour.ttf")), 15));
    

    works too.