To the best of my knowledge, the AWT API does not expose underlying Font information. If you can get to it, I would expect it to be implementation dependent. Certainly, comparing the font mapping files in a couple of JRE lib directories, I can see that they are not defined in a consistent way.
You could load your own fonts, but that seems a little wasteful given you know the platform comes with what you need.
This is a hack that loads a JRE font:
private static Font loadMonospacedFont(Display display) {
String jreHome = System.getProperty("java.home");
File file = new File(jreHome, "/lib/fonts/LucidaTypewriterRegular.ttf");
if (!file.exists()) {
throw new IllegalStateException(file.toString());
}
if (!display.loadFont(file.toString())) {
throw new IllegalStateException(file.toString());
}
final Font font = new Font(display, "Lucida Sans Typewriter", 10,
SWT.NORMAL);
display.addListener(SWT.Dispose, new Listener() {
public void handleEvent(Event event) {
font.dispose();
}
});
return font;
}
It works on IBM/Win32/JRE1.4, Sun/Win32/JRE1.6, Sun/Linux/JRE1.6, but is a pretty fragile approach. Depending on your needs for I18N, it could be trouble there too (I haven't checked).
Another hack would be to test the fonts available on the platform:
public class Monotest {
private static boolean isMonospace(GC gc) {
final String wide = "wgh8";
final String narrow = "1l;.";
assert wide.length() == narrow.length();
return gc.textExtent(wide).x == gc.textExtent(narrow).x;
}
private static void testFont(Display display, Font font) {
Image image = new Image(display, 100, 100);
try {
GC gc = new GC(image);
try {
gc.setFont(font);
System.out.println(isMonospace(gc) + "\t"
+ font.getFontData()[0].getName());
} finally {
gc.dispose();
}
} finally {
image.dispose();
}
}
private static void walkFonts(Display display) {
final boolean scalable = true;
for (FontData fontData : display.getFontList(null, scalable)) {
Font font = new Font(display, fontData);
try {
testFont(display, font);
} finally {
font.dispose();
}
}
}
public static void main(String[] args) {
Display display = new Display();
try {
walkFonts(display);
} finally {
display.dispose();
}
}
}
This probably isn't a good approach as it may leave you exposed to locale issues. Besides, you don't know if the first monospaced font you come across isn't some windings icon set.
The best approach may just be to take your best guess based on a font/locale mapping whitelist and make sure that the users can easily reconfigure the UI to suit themselves via FontDialog.