我刚刚遇到了Java字体类的一个非常奇怪的行为.
如果我像这样创建一个普通的"Verdana"家族字体,
Font font = new Font("Verdana", Font.PLAIN, 12);
Run Code Online (Sandbox Code Playgroud)
我希望这个字体是一个非粗体字体,引用我系统上安装的普通"Verdana"字体.我使用的是Windows 7,因此相应的字体应该是"Windows/Fonts"文件夹中的"verdana.ttf".
虽然这似乎有效,但实例化的字体会在我调用时改变其行为
GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
Run Code Online (Sandbox Code Playgroud)
在使用字体之前(即在字体内部绑定到任何系统字体之前).在这种情况下,字体似乎在我的系统上引用了"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);
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
如果enableStrangeBug设置为false,则会显示一个标签,显示带有预期的普通"Verdana"字体的"Some Text".输出是:
Font: java.awt.Font[family=Verdana,name=Verdana,style=plain,size=12]
Family: Verdana
Name: Verdana
Font name: Verdana
PS name: Verdana
Run Code Online (Sandbox Code Playgroud)
如果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
Run Code Online (Sandbox Code Playgroud)
我很确定这是一个错误,但我想知道其他人是否在不同系统上遇到相同的行为.我使用的是Windows 7,Java 7和Java 8的行为相同.以下Verdana字体安装在我的"Fonts"文件夹中:verdana.ttf,verdanab.ttf,verdanai.ttf和verdanaz.ttf.
我在开发类似于此处描述的字体的JComboBox时遇到了这个问题,它遇到了同样的问题:JComboBox的初始元素通过调用初始化GraphicsEnvironment#getAvailableFontFamilyNames(),这导致弹出窗口中的某些字体以粗体显示它们应该显示为普通字体.
有没有人知道这个问题的解决方法,所以这个答案中的JComboBox 初始化为所有已安装的字体系列的正确的普通字体?
另外:有谁知道导致这个问题的原因是什么?它似乎与"Verdana"字体没有直接关系,因为例如"Tahoma"字体系列在我的系统上存在同样的问题.另一方面,"Times New Roman"或"Arial"字体似乎工作得很好......
UPDATE
我刚刚发现了一个肮脏的解决方法 - 如果在Java类中包含以下静态初始化,则该错误会神奇地消失:
static{
for (Font f : GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts()) {
f.getPSName();
}
}
Run Code Online (Sandbox Code Playgroud)
但是,由于这种解决方法与错误本身一样奇怪,我很乐意接受任何答案,提供比这个更好的解决方案和/或更多信息.
| 归档时间: |
|
| 查看次数: |
617 次 |
| 最近记录: |