这些 Java 教程是针对 JDK 8 编写的。本页中描述的示例和实践不利用后续版本中引入的改进,并且可能使用不再可用的技术。
有关 Java SE 9 和后续版本中更新的语言特性的摘要,请参阅 Java 语言更改。
有关所有 JDK 版本的新功能、增强功能以及已删除或弃用选项的信息,请参阅 JDK 发行说明。
如果您有一段带有样式的文本,想要将其适应特定的宽度,可以使用LineBreakMeasurer
类。该类可以将样式文本分成多行,以便其适应特定的视觉进度。每一行都以TextLayout
对象的形式返回,该对象表示不可更改的样式字符数据。但是,该类还可以访问布局信息。 TextLayout
的getAscent
和getDescent
方法返回有关用于在组件中定位行的字体的信息。文本存储为AttributedCharacterIterator
对象,以便可以将字体和字号属性与文本一起存储。
以下小程序使用LineBreakMeasurer
,TextLayout
和AttributedCharacterIterator
将一段带有样式的文本定位在组件内。
此小程序的完整代码在
中。LineBreakSample.java
以下代码使用字符串vanGogh
创建一个迭代器。然后获取迭代器的起始和结束位置,并从迭代器创建一个新的LineBreakMeasurer
。
AttributedCharacterIterator paragraph = vanGogh.getIterator(); paragraphStart = paragraph.getBeginIndex(); paragraphEnd = paragraph.getEndIndex(); FontRenderContext frc = g2d.getFontRenderContext(); lineMeasurer = new LineBreakMeasurer(paragraph, frc);
窗口的大小用于确定应该在哪里断行。此外,对于段落中的每一行,还创建了一个TextLayout
对象。
// Set break width to width of Component. float breakWidth = (float)getSize().width; float drawPosY = 0; // Set position to the index of the first // character in the paragraph. lineMeasurer.setPosition(paragraphStart); // Get lines from until the entire paragraph // has been displayed. while (lineMeasurer.getPosition() < paragraphEnd) { TextLayout layout = lineMeasurer.nextLayout(breakWidth); // Compute pen x position. If the paragraph // is right-to-left we will align the // TextLayouts to the right edge of the panel. float drawPosX = layout.isLeftToRight() ? 0 : breakWidth - layout.getAdvance(); // Move y-coordinate by the ascent of the // layout. drawPosY += layout.getAscent(); // Draw the TextLayout at (drawPosX,drawPosY). layout.draw(g2d, drawPosX, drawPosY); // Move y-coordinate in preparation for next // layout. drawPosY += layout.getDescent() + layout.getLeading(); }
TextLayout
类通常不会直接由应用程序创建。然而,当应用程序需要直接处理已应用样式(文本属性)到文本特定位置时,这个类非常有用。例如,在段落中以斜体绘制一个单词,应用程序需要执行测量并为每个子字符串设置字体。如果文本是双向的,这个任务就不那么容易正确完成。从AttributedString
对象创建一个TextLayout
对象可以帮助你解决这个问题。请参阅Java SE规范获取有关TextLayout
的更多信息。