Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to Get a Monospaced Font

554 views
Skip to first unread message

KevinSimonson

unread,
Nov 26, 2010, 7:02:13 PM11/26/10
to
I'm trying to draw strings to a <JPanel>, and would like them to be
drawn in a font where each character has the same pixel width. I had
thought that "Courier" was such a font, so I wrote the following
program to verify that its characters do in fact have the same pixel
width, but when I tried running it I saw that they did not. For
example, the small "i" is very much narrower than the capital "W".
Can someone tell me a font I can use that might have a
chance of being monospaced?

I think I asked something similar to this before, and somebody told me
that different machines have different fonts, so I couldn't count on
getting an answer that was generally applicable. If that is true, how
can I find out which fonts my machine has? Any information would be
greatly appreciated.

Kevin S

import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;

public class FrameChars extends JPanel
{
private Font courier12;
private int lttrWdth;

private FrameChars ( int lw)
{
lttrWdth = lw;
Font courier12 = new Font( "Courier", Font.PLAIN, 12);
setPreferredSize( new Dimension( 800, 600));
setBackground( Color.black);
}

public void paintComponent ( Graphics page)
{
super.paintComponent( page);
page.setFont( courier12);
page.setColor( Color.blue);
page.drawRect( 60, 60, 26 * lttrWdth, 24);
for (int lttr = 1; lttr < 26; lttr++)
{ page.drawLine( 60 + lttr * lttrWdth, 60, 60 + lttr * lttrWdth,
84);
}
page.drawLine( 60, 72, 60 + 26 * lttrWdth, 72);
page.setColor( Color.green);
page.drawString( "abcdefghijklmnopqrstuvwxyz", 62, 70);
page.drawString( "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 62, 82);
}

public static void main ( String[] arguments)
{
if (arguments.length == 1)
{ FrameChars fc = new
FrameChars( Integer.parseInt( arguments[ 0]));
JFrame fcFrame = new JFrame( "FrameChars " + arguments[ 0]);
fcFrame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE);
fcFrame.getContentPane().add( fc);
fcFrame.pack();
fcFrame.setVisible( true);
}
else
{ System.out.println( "Usage is\n java FrameChars <lttr-wdth>");
}
}
}

Martin Gregorie

unread,
Nov 26, 2010, 7:30:10 PM11/26/10
to
On Fri, 26 Nov 2010 16:02:13 -0800, KevinSimonson wrote:

> I'm trying to draw strings to a <JPanel>, and would like them to be
> drawn in a font where each character has the same pixel width. I had
> thought that "Courier" was such a font, so I wrote the following program
> to verify that its characters do in fact have the same pixel width, but
> when I tried running it I saw that they did not.
>

I think the most portable approach is to use the 'Monospace' generic font
because Courier isn't always available, but I'm with you: Monospace
should be closer to equal glyph widths. IME it does not guarantee equal
width characters on my system (Sun Java 1.6.0_22, Linux Fedora 12) though
the description of Monospace implies that it should be the case.


--
martin@ | Martin Gregorie
gregorie. | Essex, UK
org |

markspace

unread,
Nov 26, 2010, 8:40:35 PM11/26/10
to
On 11/26/2010 4:30 PM, Martin Gregorie wrote:

> I think the most portable approach is to use the 'Monospace' generic font
> because Courier isn't always available, but I'm with you: Monospace
> should be closer to equal glyph widths.


I haven't had time to experiment with this personally, but something in
here might help:

<http://download.oracle.com/javase/1.3/docs/guide/intl/physicalfont.html>

Martin Gregorie

unread,
Nov 26, 2010, 10:00:18 PM11/26/10
to

Thats good to know except that you have to be familiar with the fonts to
know which, if any, correspond to the logical fonts, e.g. Monospace, so
as a piece of documentation its useless because it fails to provide that
mapping information.

The other thing that's missing is any documentation of the way that
JTextField and JTextArea convert the 'columns' argument into a pixel
width. IME any constructor that uses this argument to set the field width
invariably creates a field that is around twice the width needed to
display the specified number of glyphs.

It doesn't take a genius to say what default typeface, weight and size is
used to calculate the field size and to explain how this will vary if
other typefaces, weights and sizes are used for the field content, so WTF
isn't this information, or at least a link to it, part of the class
documentation?

John B. Matthews

unread,
Nov 26, 2010, 10:01:39 PM11/26/10
to
In article
<df5fc2e0-7995-4cbc...@n2g2000pre.googlegroups.com>,
KevinSimonson <kvns...@hotmail.com> wrote:

> Can someone tell me a font I can use that might have a
> chance of being monospaced?

Java supports logical fonts having the names Serif, SansSerif,
Monospaced, Dialog, and DialogInput. The logical font names are mapped
to physical fonts by the JRE. As Martin Gregorie suggests, you're
probably looking for Monospaced.

<http://download.oracle.com/javase/6/docs/api/java/awt/Font.html>

Here's a little demo of FontMetrics, "which encapsulates information
about the rendering of a particular font on a particular screen."

<http://download.oracle.com/javase/6/docs/api/java/awt/FontMetrics.html>

import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;

import java.awt.FontMetrics;
import java.awt.Rectangle;

public class FrameChars extends JPanel {

private static final int W = 640;
private static final int H = 480;
private static Font font = new Font("Monospaced", Font.PLAIN, 32);

private FrameChars() {
setPreferredSize(new Dimension(W, H));
setBackground(Color.black);
}

@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
render(g, "abcdefghijklmnopqrstuvwxyz", 32, 2 * H / 5);
render(g, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 32, 3 * H / 5);
}

private void render(Graphics g, String s, int x, int y) {
g.setFont(font);
g.setColor(Color.green);
g.drawString(s, x, y);
g.setColor(Color.blue);
FontMetrics fm = g.getFontMetrics();
Rectangle r = fm.getStringBounds(s, g).getBounds();
g.drawRect(r.x + x, r.y + y, r.width, r.height);
}

public static void main(String[] arguments) {
FrameChars fc = new FrameChars();
JFrame fcFrame = new JFrame("FrameChars");
fcFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
fcFrame.getContentPane().add(fc);
fcFrame.pack();
fcFrame.setVisible(true);
}
}

FWIW, I'm wary of relying on font spacing for alignment; that's what
layout managers are for.

--
John B. Matthews
trashgod at gmail dot com
<http://sites.google.com/site/drjohnbmatthews>

Martin Gregorie

unread,
Nov 27, 2010, 9:00:45 AM11/27/10
to
On Fri, 26 Nov 2010 22:01:39 -0500, John B. Matthews wrote:

>
> FWIW, I'm wary of relying on font spacing for alignment; that's what
> layout managers are for.
>

Agreed, but AFAIK the layout manager doesn't set the width of the
JTextField and JTextArea text entry box if you use the constructor that
specifies it as a character count. As the risk of appearing boring, I'd
again point out that doing so always to make a text area thats about 220%
of the required width. I'd like to know why and where this algorithm is
documented. Is it buggy?

Roedy Green

unread,
Nov 27, 2010, 11:19:38 AM11/27/10
to
On Fri, 26 Nov 2010 16:02:13 -0800 (PST), KevinSimonson
<kvns...@hotmail.com> wrote, quoted or indirectly quoted someone who
said :

>I think I asked something similar to this before, and somebody told me
>that different machines have different fonts, so I couldn't count on
>getting an answer that was generally applicable. If that is true, how
>can I find out which fonts my machine has? Any information would be
>greatly appreciated.

see http://mindprod.com/jgloss/logicalfonts.html

what you want is Monospaced in Java and monospace for CSS.

See http://mindprod.com/applet/fontshower.html
to see the official names of what fonts are available on any given
machine, and what they look like and roughly what characters they
support.
--
Roedy Green Canadian Mind Products
http://mindprod.com

If you give your kitchen floor a quick steam mop every few days, you will find you never have to get out buckets and brushes for deep cleaning. Similary, if you keep your code tidy, refactoring as you go, you probably won't need major rewrites.

John B. Matthews

unread,
Nov 27, 2010, 11:33:47 AM11/27/10
to
In article <icr2ud$i91$1...@localhost.localdomain>,
Martin Gregorie <mar...@address-in-sig.invalid> wrote:

Excellent question: "By default this is defined to be the width of the
character m for the font used." Peeking at the implementation, I see
getPreferredSize() calls getColumnWidth():

<http://download.oracle.com/javase/6/docs/api/javax/swing/JTextField.html>

Martin Gregorie

unread,
Nov 27, 2010, 1:32:29 PM11/27/10
to

Interestingly getColumnWidth() is said to be redefinable to return some
other value, but as there is no method for setting a different column
width I don't see how you'd do that apart from extending the class and
overriding both it and getPreferredSize().

Roedy Green

unread,
Nov 27, 2010, 2:24:24 PM11/27/10
to
On Fri, 26 Nov 2010 17:40:35 -0800, markspace <nos...@nowhere.com>

wrote, quoted or indirectly quoted someone who said :

>


>I haven't had time to experiment with this personally, but something in
>here might help:
>
><http://download.oracle.com/javase/1.3/docs/guide/intl/physicalfont.html>

note there is an error on that page
font.ITALIC should read Font.ITALIC

Also the names of the fonts are wrong on the page..

see http://mindprod.com/jgloss/physicalfonts.html
http://mindprod.com/jgloss/bundledfonts.html
http://mindprod.com/jgloss/freefonts.html
http://mindprod.com/jgloss/downloadablefonts.html

John B. Matthews

unread,
Nov 27, 2010, 3:38:53 PM11/27/10
to
In article <icrirs$mle$1...@localhost.localdomain>,
Martin Gregorie <mar...@address-in-sig.invalid> wrote:

> On Sat, 27 Nov 2010 11:33:47 -0500, John B. Matthews wrote:
>
> > In article <icr2ud$i91$1...@localhost.localdomain>,
> > Martin Gregorie <mar...@address-in-sig.invalid> wrote:
> >
> >> Agreed, but AFAIK the layout manager doesn't set the width of the
> >> JTextField and JTextArea text entry box if you use the constructor
> >> that specifies it as a character count. As the risk of appearing
> >> boring, I'd again point out that doing so always to make a text
> >> area thats about 220% of the required width. I'd like to know why
> >> and where this algorithm is documented. Is it buggy?
> >
> > Excellent question: "By default this is defined to be the width of
> > the character m for the font used." Peeking at the implementation,
> > I see getPreferredSize() calls getColumnWidth():
> >
> > <http://download.oracle.com/javase/6/docs/api/javax/swing/JTextField.html>
> >
> Interestingly getColumnWidth() is said to be redefinable to return
> some other value, but as there is no method for setting a different
> column width I don't see how you'd do that apart from extending the
> class and overriding both it and getPreferredSize().

I've never had occasion to override getColumnWidth(), but I guess
that's what "redefine" implies. Can one infer from the wording that
getPreferredSize() calls getColumnWidth()?

This may be one of those cases where "design and document for
inheritance" could be more explicit.

Knute Johnson

unread,
Nov 27, 2010, 8:04:40 PM11/27/10
to
On 11/26/2010 04:02 PM, KevinSimonson wrote:
> I'm trying to draw strings to a<JPanel>, and would like them to be
> drawn in a font where each character has the same pixel width. I had
> thought that "Courier" was such a font, so I wrote the following
> program to verify that its characters do in fact have the same pixel
> width, but when I tried running it I saw that they did not. For
> example, the small "i" is very much narrower than the capital "W".
> Can someone tell me a font I can use that might have a
> chance of being monospaced?
>
> I think I asked something similar to this before, and somebody told me
> that different machines have different fonts, so I couldn't count on
> getting an answer that was generally applicable. If that is true, how
> can I find out which fonts my machine has? Any information would be
> greatly appreciated.
>
> Kevin S

I have never had a problem with Font.MONOSPACED giving me something
other than an monospaced font but it will be mapped to some
indeterminate physical font. Courier can be tricky because there are
Couriers that aren't monospaced. There are numerous monospaced fonts on
every machine I've ever used however. One thing to keep in mind though,
is that you can package fonts with your application. There are methods
of Font to load a font from a file. TrueType fonts are usable on either
Windows or Linux operating systems.

I had a job a few years back that required some drawing on a JPanel with
a monospaced font that wasn't present in the machines we were using. We
originally started loading all the machines with the font but then
discovered that we could just load the font from a file and in the end
that was much easier.

--

Knute Johnson
s/nospam/knute2010/

Knute Johnson

unread,
Nov 27, 2010, 8:06:27 PM11/27/10
to
On 11/26/2010 04:02 PM, KevinSimonson wrote:
> I'm trying to draw strings to a<JPanel>, and would like them to be
> drawn in a font where each character has the same pixel width. I had
> thought that "Courier" was such a font, so I wrote the following
> program to verify that its characters do in fact have the same pixel
> width, but when I tried running it I saw that they did not. For
> example, the small "i" is very much narrower than the capital "W".
> Can someone tell me a font I can use that might have a
> chance of being monospaced?
>
> I think I asked something similar to this before, and somebody told me
> that different machines have different fonts, so I couldn't count on
> getting an answer that was generally applicable. If that is true, how
> can I find out which fonts my machine has? Any information would be
> greatly appreciated.
>
> Kevin S

I have never had a problem with Font.MONOSPACED giving me something

Roedy Green

unread,
Nov 27, 2010, 10:29:19 PM11/27/10
to
On Fri, 26 Nov 2010 16:02:13 -0800 (PST), KevinSimonson
<kvns...@hotmail.com> wrote, quoted or indirectly quoted someone who
said :

>I think I asked something similar to this before, and somebody told me


>that different machines have different fonts, so I couldn't count on
>getting an answer that was generally applicable. If that is true, how
>can I find out which fonts my machine has? Any information would be
>greatly appreciated.

see http://mindprod.com/jgloss/logicalfonts.html

what you want is Monospaced in Java and monospace for CSS.

See http://mindprod.com/applet/fontshower.html
to see the official names of what fonts are available on any given
machine, and what they look like and roughly what characters they
support.

Roedy Green

unread,
Nov 28, 2010, 3:21:56 AM11/28/10
to
On Fri, 26 Nov 2010 17:40:35 -0800, markspace <nos...@nowhere.com>
wrote, quoted or indirectly quoted someone who said :

>


>I haven't had time to experiment with this personally, but something in
>here might help:
>
><http://download.oracle.com/javase/1.3/docs/guide/intl/physicalfont.html>

note there is an error on that page
font.ITALIC should read Font.ITALIC

Also the names of the fonts are wrong on the page..

--

Roedy Green

unread,
Nov 28, 2010, 3:21:23 AM11/28/10
to
On Fri, 26 Nov 2010 16:02:13 -0800 (PST), KevinSimonson
<kvns...@hotmail.com> wrote, quoted or indirectly quoted someone who
said :

>I think I asked something similar to this before, and somebody told me


>that different machines have different fonts, so I couldn't count on
>getting an answer that was generally applicable. If that is true, how
>can I find out which fonts my machine has? Any information would be
>greatly appreciated.

see http://mindprod.com/jgloss/logicalfonts.html

what you want is Monospaced in Java and monospace for CSS.

See http://mindprod.com/applet/fontshower.html
to see the official names of what fonts are available on any given
machine, and what they look like and roughly what characters they
support.

Roedy Green

unread,
Nov 29, 2010, 12:41:21 PM11/29/10
to
On Fri, 26 Nov 2010 16:02:13 -0800 (PST), KevinSimonson
<kvns...@hotmail.com> wrote, quoted or indirectly quoted someone who
said :

>I think I asked something similar to this before, and somebody told me


>that different machines have different fonts, so I couldn't count on
>getting an answer that was generally applicable. If that is true, how
>can I find out which fonts my machine has? Any information would be
>greatly appreciated.

see http://mindprod.com/jgloss/logicalfonts.html

0 new messages