No word wrapping is done when you draw a string in an applet, even
if you embed newlines in the string with \n
. If you
expect that a string may not fit in the applet, you should probably
use a TextArea Component instead. You'll learn about text areas and
other AWT Components next class. However there are times when you
will need to concern yourself with how much space a particular
string will occupy. You find this out with a FontMetrics
object. FontMetrics
allow you to
determine the height, width or other useful characteristics of a
particular string, character, or array of characters in a
particular font.
As an example the following program expands on the DrawString applet. Previously text would run off the side of the page if the string was too long to fit in the applet. Now the string will wrap around if necessary.
In order to tell where and whether to wrap the String
, you need to measure the string, not its length in
characters which can be variable but rather its width and height in
pixels. Measurements of this sort on strings clearly depend on the
font that's used to draw the string. All other things being equal a
14 point string will be wider than the same string in 12 or 10
point type.
To measure character and string sizes you need to look at the
FontMetrics
of the current font. To get a FontMetrics
object for the current Graphics
object you use the java.awt.Graphics.getFontMetrics()
method. From java.awt.FontMetrics
you'll need fm.stringWidth(String s)
to return the width of a string in
a particular font, and fm.getLeading()
to get the
appropriate line spacing for the font. There are many more methods
in java.awt.FontMetrics
that let you measure the
heights and widths of specific characters as well as ascenders,
descenders and more, but these three methods will be sufficient for
this program.
Finally you'll need the StringTokenizer
class from
java.util
to split up the String
into
individual words. However you do need to be careful lest some
annoying beta tester (or, worse yet, end user) tries to see what
happens when they feed the word antidisestablishmentarianism or
supercalifragilisticexpialidocious into an applet that's 50 pixels
across.
import java.applet.*;
import java.awt.*;
import java.util.*;
public class WrapTextApplet extends Applet {
private String inputFromPage;
public void init() {
this.inputFromPage = this.getParameter("Text");
}
public void paint(Graphics g) {
int line = 1;
int linewidth = 0;
int margin = 5;
StringBuffer sb = new StringBuffer();
FontMetrics fm = g.getFontMetrics();
StringTokenizer st = new StringTokenizer(inputFromPage);
while (st.hasMoreTokens()) {
String nextword = st.nextToken();
if (fm.stringWidth(sb.toString() + nextword) + margin <
this.getSize().width) {
sb.append(nextword);
sb.append(' ');
}
else if (sb.length() == 0) {
g.drawString(nextword, margin, line*fm.getHeight());
line++;
}
else {
g.drawString(sb.toString(), margin, line*fm.getHeight());
sb = new StringBuffer(nextword + " ");
line++;
}
}
if (sb.length() > 0) {
g.drawString(sb.toString(), margin, line*fm.getHeight());
line++;
}
}
}