60

I wrote a program in Java that uses a special font that by default doesn't exist on any operating system.

Is it possible in Java to add this special font to the operation system? For example, in Windows, to copy this font to the special Fonts folder.

If it is possible, how?

Cᴏʀʏ
  • 105,112
  • 20
  • 162
  • 194
Mahdi_Nine
  • 14,205
  • 26
  • 82
  • 117

5 Answers5

67

If you include a font file (otf, ttf, etc.) in your package, you can use the font in your application via the method described here:

Oracle Java SE 6: java.awt.Font

There is a tutorial available from Oracle that shows this example:

try {
     GraphicsEnvironment ge = 
         GraphicsEnvironment.getLocalGraphicsEnvironment();
     ge.registerFont(Font.createFont(Font.TRUETYPE_FONT, new File("A.ttf")));
} catch (IOException|FontFormatException e) {
     //Handle exception
}

I would probably wrap this up in some sort of resource loader though as to not reload the file from the package every time you want to use it.

An answer more closely related to your original question would be to install the font as part of your application's installation process. That process will depend on the installation method you choose. If it's not a desktop app you'll have to look into the links provided.

Aly
  • 847
  • 1
  • 6
  • 30
Cᴏʀʏ
  • 105,112
  • 20
  • 162
  • 194
  • 7
    Please describe here how to do it, not just link to another page. – Magmatic May 22 '14 at 01:55
  • I have checked that by this way, only this java program can list/use the new font, while other parallel java apps remain unknown about this. But if you install another font with some similar name with system ones, it may substitute the latter one and other applications may stop to work consistently... which I have encountered the other day. So, never install something new in system scope, and only do it if you are 100% sure what you are doing. – WesternGun Mar 10 '17 at 09:02
23

Here is how I did it!

//create the font

try {
    //create the font to use. Specify the size!
    Font customFont = Font.createFont(Font.TRUETYPE_FONT, new File("Fonts\\custom_font.ttf")).deriveFont(12f);
    GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
    //register the font
    ge.registerFont(customFont);
} catch (IOException e) {
    e.printStackTrace();
} catch(FontFormatException e) {
    e.printStackTrace();
}

//use the font
yourSwingComponent.setFont(customFont);
Florin Virtej
  • 435
  • 4
  • 7
  • 2
    Can't you just call ge.registerFont with the variable customFont as its parameter to stop the excessive typing? – tobahhh Oct 06 '16 at 22:28
  • 1
    Can you please extend the answer a bit? Is this different from the solution provided by dogbane? Is is necessary to call `createFont` twice? If it is, why? – Suma Nov 27 '18 at 07:55
13

If you want to use the font to draw with graphics2d or similar, this works:

InputStream stream = ClassLoader.getSystemClassLoader().getResourceAsStream("roboto-bold.ttf")
Font font = Font.createFont(Font.TRUETYPE_FONT, stream).deriveFont(48f)
Heinrisch
  • 5,835
  • 4
  • 33
  • 43
  • 4
    For clarity, the `48f` here is the font size passed as a float. If you pass it in as an integer it doesn't work properly because that method is expecting int constants such as `Font.BOLD`. If you are using different sizes or styles of a single font, you can derive all of them from your single `Font` object. – Stephen Ostermiller Nov 09 '17 at 15:34
12

From the Java tutorial, you need to create a new font and register it in the graphics environment:

GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
ge.registerFont(Font.createFont(Font.TRUETYPE_FONT, new File("A.ttf")));

After this step is done, the font is available in calls to getAvailableFontFamilyNames() and can be used in font constructors.

adneal
  • 30,484
  • 10
  • 122
  • 151
dogbane
  • 266,786
  • 75
  • 396
  • 414
0

Configuration:

final GraphicsEnvironment GE = GraphicsEnvironment.getLocalGraphicsEnvironment();
final List<String> AVAILABLE_FONT_FAMILY_NAMES = Arrays.asList(GE.getAvailableFontFamilyNames());
try {
    final List<File> LIST = Arrays.asList(
        new File("font/JetBrainsMono/JetBrainsMono-Thin.ttf"),
        new File("font/JetBrainsMono/JetBrainsMono-Light.ttf"),
        new File("font/Roboto/Roboto-Light.ttf"),
        new File("font/Roboto/Roboto-Regular.ttf"),
        new File("font/Roboto/Roboto-Medium.ttf")
     );
     for (File LIST_ITEM : LIST) {
         if (LIST_ITEM.exists()) {
             Font FONT = Font.createFont(Font.TRUETYPE_FONT, LIST_ITEM);
             if (!AVAILABLE_FONT_FAMILY_NAMES.contains(FONT.getFontName())){ 
                 GE.registerFont(FONT);
             }
         }
     }
} catch (FontFormatException | IOException exception) {
    JOptionPane.showMessageDialog(null, exception.getMessage());
}

Usage example:

JLabel label1 = new JLabel("TEXT1");
label1.setFont(new Font("Roboto Medium", Font.PLAIN, 13));

JLabel label2 = new JLabel("TEXT2");
label2.setFont(new Font("Roboto", Font.PLAIN, 13));

Note: Only existing fonts that are not available in the system are registered.