How to Get a Monospaced Font

K

KevinSimonson

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>");
}
}
}
 
M

Martin Gregorie

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.
 
M

Martin Gregorie

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>

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?
 
J

John B. Matthews

KevinSimonson said:
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.
 
M

Martin Gregorie

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?
 
R

Roedy Green

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.
 
J

John B. Matthews

Martin Gregorie said:
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>
 
M

Martin Gregorie

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().
 
R

Roedy Green

J

John B. Matthews

Martin Gregorie said:
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.
 
K

Knute Johnson

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.
 
K

Knute Johnson

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.
 
R

Roedy Green

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.
 
R

Roedy Green

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.
 
R

Roedy Green

R

Roedy Green

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,902
Latest member
Elena68X5

Latest Threads

Top