I just encountered a very strange behavior of the Java font class.
If I create a plain Font of the "Verdana" family like so,
Font font = new Font("Verdana", Font.PLAIN, 12);
I'd expect this font to be a non-bold font referencing the plain "Verdana" font installed on my system. I'm using Windows 7, so the corresponding font should be "verdana.ttf" in the "Windows/Fonts" folder.
While this seems to be working, the instantiated font changes its behavior if I invoke
GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
before the font is used (i.e. before the font is internally bound to any system font). In this case the font seems to reference the "Verdana Bold" font ("verdanab.ttf") on my system.
Here is some test code, that reproduces this problem:
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);
}
});
}
}
If enableStrangeBug
is set to false, a label is shown that displays "Some Text" with the expected plain "Verdana" font. The output is:
Font: java.awt.Font[family=Verdana,name=Verdana,style=plain,size=12]
Family: Verdana
Name: Verdana
Font name: Verdana
PS name: Verdana
If enableStrangeBug
is on the other hand set to true, the labels font seems to be "Verdana Bold" and the output is:
Font: java.awt.Font[family=Verdana,name=Verdana,style=plain,size=12]
Family: Verdana
Name: Verdana
Font name: Verdana Bold
PS name: Verdana-Bold
I'm pretty sure this is a bug, but I'd like to know if others here encounter the same behavior on different systems. I'm using Windows 7 and the behavior is the same for both Java 7 and Java 8. The following Verdana fonts are installed in my "Fonts" folder: verdana.ttf, verdanab.ttf, verdanai.ttf and verdanaz.ttf.
I first encountered this while developing a JComboBox for fonts similar to the one described here, which suffers from the same problem: The initial elements of the JComboBox get initialized by calling GraphicsEnvironment#getAvailableFontFamilyNames()
, which results in some of the fonts in the popup being displayed in bold although they should be displayed as plain fonts.
Does anyone here know a workaround for this problem, so the JComboBox in this answer gets initialized with the correct plain fonts for all installed font families?
Also: Does anyone know what causes this problem? It doesn't seem to be directly related to the "Verdana" font, because e.g. the "Tahoma" font family has the same problem on my system. On the other hand the "Times New Roman" or "Arial" font families seem to work fine...
UPDATE
I just found a dirty workaround - if one includes the following static initialization in the Java class, the bug magically disappears:
static{
for (Font f : GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts()) {
f.getPSName();
}
}
But since this workaround is just as strange as the bug itself, I will gladly accept any answer with a better solution than this one and/or with some more information.
See http://bugs.java.com/bugdatabase/view_bug.do?bug_id=7083197 The bug report contains an explanation of how the problem occurs, but no workaround.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With