GraphicsEnvironment#getAvailableFontFamilyNames()之后出现奇怪的字体行为?

时间:2014-05-05 10:46:55

标签: java fonts awt

我刚刚遇到了Java字体类的一个非常奇怪的行为。

如果我创建了" Verdana"像这样的家庭,

Font font = new Font("Verdana", Font.PLAIN, 12);

我希望这个字体是一个非粗体字体,引用普通" Verdana"字体安装在我的系统上。我使用的是Windows 7,因此相应的字体应为" verdana.ttf"在" Windows / Fonts"文件夹中。

虽然这似乎有效,但如果我调用

,实例化的字体会改变其行为
GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();

在使用字体之前(即在字体内部绑定到任何系统字体之前)。在这种情况下,字体似乎引用了" Verdana Bold"我系统上的字体(" verdanab.ttf")。

以下是一些测试代码,可以重现此问题:

import java.awt.Font;
import java.awt.GraphicsEnvironment;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;

public class JavaFontBug {

    public static void main(String[] args) {

        boolean enableStrangeBug = false;
        Font font = new Font("Verdana", Font.PLAIN, 12);

        String text;
        if (enableStrangeBug) {
            // this line enables the bug:
            GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
            text = "Some Bold Text?!";
        } else{
            text = "Some Text";
        }

        System.out.println("Font: " + font);
        System.out.println("Font name: " + font.getFontName());

        final JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JLabel label = new JLabel(text);
        label.setFont(font);
        frame.getContentPane().add(label);
        frame.pack();
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                frame.setVisible(true);
            }
        });
    }

}

如果enableStrangeBug设置为false,则会显示一个标签,显示" Some Text"与预期的平原" Verdana"字体。输出是:

Font: java.awt.Font[family=Verdana,name=Verdana,style=plain,size=12]
Family: Verdana
Name: Verdana
Font name: Verdana
PS name: Verdana

如果enableStrangeBug另一方面设置为true,则标签字体似乎是" Verdana Bold"输出是:

Font: java.awt.Font[family=Verdana,name=Verdana,style=plain,size=12]
Family: Verdana
Name: Verdana
Font name: Verdana Bold
PS name: Verdana-Bold

我很确定这是一个错误,但我想知道其他人是否在不同系统上遇到相同的行为。我使用的是Windows 7,Java 7和Java 8的行为相同。以下Verdana字体安装在我的"字体"文件夹:verdana.ttf,verdanab.ttf,verdanai.ttf和verdanaz.ttf。

我在为类似于here描述的字体开发JComboBox时遇到了这个问题,它遇到了同样的问题:JComboBox的初始元素通过调用GraphicsEnvironment#getAvailableFontFamilyNames()来初始化,这导致弹出窗口中的某些字体以粗体显示,但它们应显示为普通字体。

有没有人知道这个问题的解决方法,所以this answer中的JComboBox会使用正确的普通字体进行初始化,以便安装所有已安装的字体系列?

另外:有谁知道导致这个问题的原因是什么?它似乎与" Verdana"直接相关。字体,因为例如" Tahoma"字体系列在我的系统上有同样的问题。另一方面," Times New Roman"或" Arial"字体系列似乎工作得很好......


更新

我刚刚发现了一个肮脏的解决方法 - 如果在Java类中包含以下静态初始化,该错误会神奇地消失:

static{
    for (Font f : GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts()) {
        f.getPSName();
    }
}

但是由于这种解决方法与错误本身一样奇怪,我很乐意接受任何答案,提供比这个更好的解决方案和/或更多信息。

1 个答案:

答案 0 :(得分:1)

参见http://bugs.java.com/bugdatabase/view_bug.do?bug_id=7083197 错误报告包含对问题如何发生的解释,但没有解决方法。