我刚刚遇到了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();
}
}
但是由于这种解决方法与错误本身一样奇怪,我很乐意接受任何答案,提供比这个更好的解决方案和/或更多信息。
答案 0 :(得分:1)
参见http://bugs.java.com/bugdatabase/view_bug.do?bug_id=7083197 错误报告包含对问题如何发生的解释,但没有解决方法。