Trail: 2D Graphics
Lesson: Working with Text and Fonts
Drawing Multiple Lines of Text
Drawing Multiple Lines of Text
If you have a paragraph of styled text that you would like to fit within a specific width, you can use LineBreakMeasurer, which allows styled text to be broken into lines that fit within a particular visual advance. As you learned in the Displaying Graphics with Graphics2D trail, a TextLayout object represents unchangeable, styled character data, but it also allows access to layout information. The getAscent and getDescent methods of TextLayout return information about the font that is used to position the lines in the component. The text is stored as an AttributedCharacterIterator so the font and point size attributes can be stored with the text.

Example: LineBreakSample

The following applet positions a paragraph of styled text within a component, using LineBreakMeasurer, TextLayout and AttributedCharacterIterator.

Click this figure to run the applet.
This is a picture of the applet's GUI. To run the applet, click the picture. The applet will appear in a new browser window.

The complete code for this program is in LineBreakSample.java.

The following code creates an iterator with the string vanGogh. The start and end of the iterator is retrieved and a new LineBreakMeasurer is created from the iterator.

AttributedCharacterIterator paragraph = vanGogh.getIterator();
paragraphStart = paragraph.getBeginIndex();
paragraphEnd = paragraph.getEndIndex();
        
lineMeasurer = new LineBreakMeasurer(paragraph,
                            new FontRenderContext(null, false, false));
The size of the window is used to determine where the line should break and a TextLayout object is created for each line in the paragraph.
Dimension size = getSize();
float formatWidth = (float) size.width;    
float drawPosY = 0;
lineMeasurer.setPosition(paragraphStart);
        
while (lineMeasurer.getPosition() < paragraphEnd) {    
   TextLayout layout = lineMeasurer.nextLayout(formatWidth);

   // Move y-coordinate by the ascent of the layout.
   drawPosY += layout.getAscent();
        
   /* Compute pen x position.  If the paragraph is
      right-to-left, we want to align the TextLayouts
      to the right edge of the panel. 
    */
   float drawPosX;
   if (layout.isLeftToRight()) {
       drawPosX = 0;
   }
   else {
     drawPosX = formatWidth - layout.getAdvance();
   }
            
   // Draw the TextLayout at (drawPosX, drawPosY). 
   layout.draw(graphics2D, drawPosX, drawPosY);
            
   // Move y-coordinate in preparation for next layout.
   drawPosY += layout.getDescent() + layout.getLeading();
}
Previous page: Creating and Deriving Fonts
Next page: Manipulating and Displaying Images