如何在Java中使用自定义字体?

60

我用Java编写了一个程序,使用了一种默认情况下不存在于任何操作系统上的特殊字体。

在Java中是否有可能将这种特殊字体添加到操作系统中?例如,在Windows中将此字体复制到特殊的字体文件夹中。

如果可能的话,应该如何实现?

5个回答

67

如果您在包中包含了字体文件(otf、ttf等),您可以通过此处描述的方法在应用程序中使用字体:

Oracle Java SE 6:java.awt.Font

Oracle 提供了教程示例来演示这个过程。

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

我会建议用某种资源加载器对其进行封装,以免每次使用时都从包中重新加载文件。

更接近您原始问题的答案是将字体作为应用程序安装过程的一部分安装。该过程将取决于您选择的安装方法。如果不是桌面应用程序,则必须查看提供的链接。


7
请在此处描述如何操作,而不仅仅链接到另一个页面。 - Magmatic
我已经检查过了,通过这种方式,只有这个Java程序可以列出/使用新字体,而其他并行的Java应用程序仍然不知道这一点。但是,如果您安装了另一个具有与系统字体类似名称的字体,则可能会替换后者,并且其他应用程序可能会停止正常工作...我前几天就遇到了这种情况。因此,在系统范围内永远不要安装新内容,只有在您百分之百确定自己在做什么时才这样做。 - WesternGun

24

这是我的做法!

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

2
你不能只是调用ge.registerFont并将变量customFont作为其参数来停止过多的打字吗? - tobahhh
1
请问您能否详细说明一下答案?这与dogbane提供的解决方案有何不同?需要两次调用“createFont”吗?如果需要,为什么? - Suma

14
如果您想要使用字体进行图形绘制,可以使用以下代码:

如果你想用font在graphics2d或类似的东西里面画东西,这个方法适用:

InputStream stream = ClassLoader.getSystemClassLoader().getResourceAsStream("roboto-bold.ttf")
Font font = Font.createFont(Font.TRUETYPE_FONT, stream).deriveFont(48f)

4
为了清晰起见,这里的“48f”是传递的字体大小,以浮点数形式传递。 如果您将其作为整数传递,它无法正常工作,因为该方法期望int常量,如“Font.BOLD”。如果您使用单个字体的不同大小或样式,则可以从单个“Font”对象派生所有这些大小或样式。 - Stephen Ostermiller

12

根据Java教程,您需要创建一个新的字体并在图形环境中注册它:

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

此步骤完成后,该字体将在调用getAvailableFontFamilyNames()时可用,并且可以在字体构造函数中使用。


0

配置:

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

用法示例:

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

注意: 只有系统中不存在的现有字体才会被注册。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接