Previous | Next | Trail Map | Creating a User Interface | Working with Graphics


Working with Text

Support for working with primitive text is spread between the AWT Graphics,(in the API reference documentation) Font,(in the API reference documentation) and FontMetrics(in the API reference documentation) classes.

Drawing Text

When you're writing code to draw text, you should first consider whether you can use a text-oriented Component, such as the Label,(in the API reference documentation) TextField,(in the API reference documentation) or TextArea(in the API reference documentation) class. If a Component isn't appropriate, you can use the Graphics drawBytes(), drawChars(), or drawString() methods. Here is an example of the code that draws a string to the screen:
g.drawString("This is a string.", x, y);
For the text drawing methods, x and y specify the position of the lower left corner of the text -- not including room for the tails (descenders) on letters such as "y". Be sure to make y large enough to allow vertical space for the text, but small enough to allow room for descenders. Here is a simple applet that illustrates this point:

The top string is probably cut off, since its y argument is 5, which leaves only 5 pixels of vertical space for the string -- not enough for most fonts. The middle string probably shows up just fine, unless your applet viewer has a huge default font. Most of the letters in the bottom string display fine, except for letters with descenders. All descenders in the bottom string are cut off, since the code that displays this string doesn't allow room for them. (Here is the applet's source code.)

Note: The text-drawing methods' interpretation of x and y is different from that of the shape-drawing methods. When drawing a shape (such as a rectangle), x and y specify the upper left corner of the shape's bounding rectangle, instead of the lower left corner.

Getting Information about a Font: FontMetrics

The shape-drawing example on the previous page could be improved by choosing a font that's smaller than the usual default font. The following example does this and also enlarges the shapes to take up the space freed by the font's smaller height. Below is the improved applet (here is its code):

The example chooses the appropriate font by using a FontMetrics object to get details of the font's size. For example, the following loop (in the paint() method) ensures that the longest string displayed by the applet fits within the space each shape is allotted.

boolean textFits = false;
Font font = g.getFont();
FontMetrics fontMetrics = g.getFontMetrics();
while (!textFits) {
    if ((fontMetrics.getHeight() <= maxCharHeight) 
        && (fontMetrics.stringWidth("drawRoundRect()") 
            <= gridWidth)) {
	textFits = true;
    } else {
        g.setFont(font = new Font(font.getName(),
    			          font.getStyle(),
			          font.getSize() - 1));
        fontMetrics = g.getFontMetrics();
    }
}
The example code above uses the Graphics getFont(), setFont(), and getFontMetrics() methods to get and set the current font and to get the FontMetrics object that corresponds to the font. The example code uses the FontMetrics getHeight() and getStringWidth() methods to get vertical and horizontal size information about the font.

The following figure shows some of the information that a FontMetrics object can provide about a font's size.


[Should add label saying that the gray lines indicate the next line of text.]

Here's a summary of the FontMetrics methods that return information about a font's vertical size:
[Please excuse bad formatting in following section. It's caused by a bug in our HTML to PostScript converter.]

getAscent(), getMaxAscent()
The getAscent() method returns the number of pixels between the ascender line and the baseline. Generally, the ascender line represents the typical height of capital letters. Specifically, the ascent and descent values are chosen by the font's designer to represent the correct text "color", or density of ink, so that the text appears as the designer planned it. The ascent typically provides enough room for almost all of the characters in the font, except perhaps for accents on capital letters. The getMaxAscent() method accounts for these exceptionally tall characters.
getDescent(), getMaxDescent()
The getDescent() method returns the number of pixels between the baseline and the descender line. The getMaxDescent() method accounts for characters that descend below the descender line.
getHeight()
Returns the number of pixels normally found between the baseline of one line of text and the baseline of the next line of text. Note that this includes an allowance for leading.
getLeading()
Returns the suggested distance (in pixels) between one line of text and the next. Specifically the leading is the distance between the descender line of one line of text and the ascender line of the next line of text. By the way, leading is pronounced LEDDing.

Note that the font size (returned by the Font class getSize() method) is an abstract measurement. Theoretically, it corresponds to the ascent plus the descent. Practically, however, the font designer decides exactly how tall a "12 point" font (for example) is. For example, 12-point Times is generally shorter than 12-point Helvetica [TRUE?]. Typically, font size is measured in points, which are approximately 1/72 of an inch.

FontMetrics provides the following methods to return information about the horizontal size of a font's characters. These methods take into account the spacing around each character. More precisely, each method returns not the number of pixels taken up by a particular character (or characters), but the number of pixels by which the current point will be advanced when that character (or characters) is shown.

[It'd be nice to have a figure illustrating this.]

getMaxAdvance()
The width (in pixels) of the widest character in the font.
bytesWidth()
The width of the text represented by the specified array of bytes.
charWidth()
The width of the specified character.
charsWidth()
The width of the string represented by the specified character array.
stringWidth()
The width of the specified string.
getWidths()
The width of each of the first 256 characters in the font.


Previous | Next | Trail Map | Creating a User Interface | Working with Graphics