tags:

views:

624

answers:

4

Hi there,

I'm trying list all of the monospaced fonts available on a user's machine. I can get all of the font families in Swing via:

String[] fonts = GraphicsEnvironment.getLocalGraphicsEnvironment()
                                    .getAvailableFontFamilyNames();

Is there a way to figure out which of these are monospaced?

Thanks in advance.

+2  A: 

Compare the drawn lengths of several characters (m, i, 1, . should be a good set).

For monospaced fonts they will all be equal, for variable width fonts they won't.

toast
Can you add example code?
Jonik
+1 for the practical and simple approach; I use i and m.
Software Monkey
+1  A: 

According to this response, Java doesn't know too much about underlying font details, so you'd have to do some comparisons of the font's dimensions.

yalestar
+3  A: 
Adam Paynter
Thanks for extending your example code - it wasn't obvious how to get FontMetrics for a given Font. Still, for some reason this doesn't find any monospaced fonts on my machine (OS X)...
Jonik
I tested with one font that's known to be monospaced (java.awt.Font[family=Andale Mono,name=Andale Mono,style=plain,size=12]). For this font getWidths() returns numbers like: 7 0 4 4 4 4 4 4 0 7 7 4 7 7 4 ... :-/
Jonik
Try the updated code
Adam Paynter
Hmm, interesting; this code finds *one* monospaced font on this system: "Lucida Sans Typewriter". But fonts like "Andale Mono" and "Courier New" still fail the test (both of these at codepoint 1). When printed, the failing characters look a lot like whitespace, so I wonder if the whitespace check works correctly...
Jonik
thanks adam. works on my windows machine. I'll check it on my mac at home
Jonik: Maybe you could change the codePoint check to something like Character.isLetter(...) || Character.isDigit(...)?
Adam Paynter
Adam, thanks - after that change, it found 8 monospaced fonts on the Mac, which is presumably all of them. Also, for the record, on my Linux machine at work, the version with !Character.isWhitespace() finds 23 monospaced fonts, while with (Character.isLetter() || Character.isDigit()) it finds 29 fonts. Perhaps you could change the example code as it seems isWhitespace() cannot always be trusted... But +1 anyways!
Jonik
+1  A: 

Probably not applicable for your case, but if you simply want to set the font to a monospaced font, use the logical font name:

Font mono = new Font("Monospaced", Font.PLAIN, 12);

This will be a guaranteed monospaced font on your system.

James Van Huis