- java.lang.Object
-
- java.awt.font.LineBreakMeasurer
-
public final class LineBreakMeasurer extends Object
LineBreakMeasurer类允许将样式化文本分解为适合特定视觉前进的行(或段)。 这对于希望显示适合特定宽度的文本段落(称为包装宽度)的客户非常有用。LineBreakMeasurer使用样式文本上的迭代器构造。 迭代器的范围应该是文本中的单个段落。LineBreakMeasurer在文本中保留下一个文本段开头的位置。 最初,这个位置是文本的开头。 根据双向格式规则为段落分配总体方向(从左到右或从右到左)。 从段落中获得的所有段都与段落具有相同的方向。通过调用方法
nextLayout获得文本段,该方法返回表示适合包裹宽度的文本的TextLayout。nextLayout方法将当前位置移动到从nextLayout返回的布局的nextLayout。LineBreakMeasurer实现了最常用的换行策略:适合包装宽度的每个单词都放在行上。 如果第一个单词不适合,那么适合包装宽度的所有字符都放在该行上。 每行至少放置一个字符。该
TextLayout情况下,通过返回LineBreakMeasurer对待标签如0角空格。 希望获得制表符分隔的定位段的客户端应使用nextLayout的重载,该过载在nextLayout中采用限制偏移量。 限制偏移量应该是选项卡后面的第一个字符。 从此方法返回的TextLayout对象以提供的限制结束(或者之前,如果当前位置和限制之间的文本不完全适合包装宽度)。在将第一个段放置在一条线上之后,正在布置制表符分隔文本的客户端需要稍微不同的换行策略。 它们不应该在剩余空间中拟合部分单词,而应将完全不适合剩余空间的单词放在下一行。 可以在
nextLayout的超载中请求此策略更改,该参数采用boolean参数。 如果此参数为true,则如果第一个单词不适合给定空间,则nextLayout将返回null。 请参阅下面的选项卡示例。通常,如果用于构造
LineBreakMeasurer的文本发生更改,LineBreakMeasurer必须构造新的LineBreakMeasurer以反映更改。 (旧的LineBreakMeasurer继续正常运行,但它不会知道文本更改。)尽管如此,如果文本更改是插入或删除单个字符,LineBreakMeasurer可以通过调用insertChar或更新现有的insertChar或deleteChar。 更新现有的LineBreakMeasurer比创建新的快得多。 根据用户输入修改文本的客户端应该利用这些方法。示例 :
在组件中呈现段落
public void paint(Graphics graphics) { float dx = 0f, dy = 5f; Graphics2D g2d = (Graphics2D)graphics; FontRenderContext frc = g2d.getFontRenderContext(); AttributedString text = new AttributedString("....."); AttributedCharacterIterator paragraph = text.getIterator(); LineBreakMeasurer measurer = new LineBreakMeasurer(paragraph, frc); measurer.setPosition(paragraph.getBeginIndex()); float wrappingWidth = (float)getSize().width; while (measurer.getPosition() < paragraph.getEndIndex()) { TextLayout layout = measurer.nextLayout(wrappingWidth); dy += (layout.getAscent()); float dx = layout.isLeftToRight() ? 0 : (wrappingWidth - layout.getAdvance()); layout.draw(graphics, dx, dy); dy += layout.getDescent() + layout.getLeading(); } }使用选项卡呈现文本。 为简单起见,假设整个文本方向是从左到右
public void paint(Graphics graphics) { float leftMargin = 10, rightMargin = 310; float[] tabStops = { 100, 250 }; // assume styledText is an AttributedCharacterIterator, and the number // of tabs in styledText is tabCount int[] tabLocations = new int[tabCount+1]; int i = 0; for (char c = styledText.first(); c != styledText.DONE; c = styledText.next()) { if (c == '\t') { tabLocations[i++] = styledText.getIndex(); } } tabLocations[tabCount] = styledText.getEndIndex() - 1; // Now tabLocations has an entry for every tab's offset in // the text. For convenience, the last entry is tabLocations // is the offset of the last character in the text. LineBreakMeasurer measurer = new LineBreakMeasurer(styledText); int currentTab = 0; float verticalPos = 20; while (measurer.getPosition() < styledText.getEndIndex()) { // Lay out and draw each line. All segments on a line // must be computed before any drawing can occur, since // we must know the largest ascent on the line. // TextLayouts are computed and stored in a Vector; // their horizontal positions are stored in a parallel // Vector. // lineContainsText is true after first segment is drawn boolean lineContainsText = false; boolean lineComplete = false; float maxAscent = 0, maxDescent = 0; float horizontalPos = leftMargin; Vector layouts = new Vector(1); Vector penPositions = new Vector(1); while (!lineComplete) { float wrappingWidth = rightMargin - horizontalPos; TextLayout layout = measurer.nextLayout(wrappingWidth, tabLocations[currentTab]+1, lineContainsText); // layout can be null if lineContainsText is true if (layout != null) { layouts.addElement(layout); penPositions.addElement(new Float(horizontalPos)); horizontalPos += layout.getAdvance(); maxAscent = Math.max(maxAscent, layout.getAscent()); maxDescent = Math.max(maxDescent, layout.getDescent() + layout.getLeading()); } else { lineComplete = true; } lineContainsText = true; if (measurer.getPosition() == tabLocations[currentTab]+1) { currentTab++; } if (measurer.getPosition() == styledText.getEndIndex()) lineComplete = true; else if (horizontalPos >= tabStops[tabStops.length-1]) lineComplete = true; if (!lineComplete) { // move to next tab stop int j; for (j=0; horizontalPos >= tabStops[j]; j++) {} horizontalPos = tabStops[j]; } } verticalPos += maxAscent; Enumeration layoutEnum = layouts.elements(); Enumeration positionEnum = penPositions.elements(); // now iterate through layouts and draw them while (layoutEnum.hasMoreElements()) { TextLayout nextLayout = (TextLayout) layoutEnum.nextElement(); Float nextPosition = (Float) positionEnum.nextElement(); nextLayout.draw(graphics, nextPosition.floatValue(), verticalPos); } verticalPos += maxDescent; } }- 另请参见:
-
TextLayout
-
-
构造方法摘要
构造方法 构造器 描述 LineBreakMeasurer(AttributedCharacterIterator text, FontRenderContext frc)为指定的文本构造一个LineBreakMeasurer。LineBreakMeasurer(AttributedCharacterIterator text, BreakIterator breakIter, FontRenderContext frc)为指定的文本构造一个LineBreakMeasurer。
-
方法摘要
所有方法 实例方法 具体的方法 变量和类型 方法 描述 voiddeleteChar(AttributedCharacterIterator newParagraph, int deletePos)从文本中删除单个字符后更新此LineBreakMeasurer,并将当前位置设置为段落的开头。intgetPosition()返回此LineBreakMeasurer的当前位置。voidinsertChar(AttributedCharacterIterator newParagraph, int insertPos)在将单个字符插入文本后更新此LineBreakMeasurer,并将当前位置设置为段落的开头。TextLayoutnextLayout(float wrappingWidth)返回下一个布局,并更新当前位置。TextLayoutnextLayout(float wrappingWidth, int offsetLimit, boolean requireNextWord)返回下一个布局,并更新当前位置。intnextOffset(float wrappingWidth)返回下一个布局末尾的位置。intnextOffset(float wrappingWidth, int offsetLimit, boolean requireNextWord)返回下一个布局末尾的位置。voidsetPosition(int newPosition)设置此LineBreakMeasurer的当前位置。
-
-
-
构造方法详细信息
-
LineBreakMeasurer
public LineBreakMeasurer(AttributedCharacterIterator text, FontRenderContext frc)
为指定的文本构造一个LineBreakMeasurer。- 参数
-
text- 此LineBreakMeasurer生成TextLayout对象的文本; 文本必须至少包含一个字符; 如果通过iter提供的文本发生更改,则对此LineBreakMeasurer实例的进一步调用未定义(在某些情况下,以后调用insertChar或deleteChar时 - 请参见下文) -
frc- 包含有关正确测量文本所需的图形设备的信息; 文本测量值可能会略有不同,具体取决于设备分辨率和抗锯齿等属性; 此参数未指定LineBreakMeasurer与用户空间之间的LineBreakMeasurer - 另请参见:
-
insertChar(java.text.AttributedCharacterIterator, int),deleteChar(java.text.AttributedCharacterIterator, int)
-
LineBreakMeasurer
public LineBreakMeasurer(AttributedCharacterIterator text, BreakIterator breakIter, FontRenderContext frc)
为指定的文本构造一个LineBreakMeasurer。- 参数
-
text- 此LineBreakMeasurer生成TextLayout对象的文本; 文本必须至少包含一个字符; 如果通过iter提供的文本发生更改,则对此LineBreakMeasurer实例的进一步调用未定义(在某些情况下,之后调用insertChar或deleteChar时 - 请参见下文) -
breakIter- 定义换行符的BreakIterator -
frc- 包含有关正确测量文本所需的图形设备的信息; 文本测量值可能会略有不同,具体取决于设备分辨率和抗锯齿等属性; 此参数未指定LineBreakMeasurer与用户空间之间的LineBreakMeasurer - 异常
-
IllegalArgumentException- 如果文本少于一个字符 - 另请参见:
-
insertChar(java.text.AttributedCharacterIterator, int),deleteChar(java.text.AttributedCharacterIterator, int)
-
-
方法详细信息
-
nextOffset
public int nextOffset(float wrappingWidth)
返回下一个布局末尾的位置。 不更新此LineBreakMeasurer的当前位置。- 参数
-
wrappingWidth- 下一个布局中文本允许的最大可见提前量 - 结果
-
表示下一个
TextLayout限制的文本中的偏移量。
-
nextOffset
public int nextOffset(float wrappingWidth, int offsetLimit, boolean requireNextWord)返回下一个布局末尾的位置。 不更新此LineBreakMeasurer的当前位置。- 参数
-
wrappingWidth- 下一个布局中文本允许的最大可见提前量 -
offsetLimit- 第一个不能包含在下一个布局中的字符,即使限制后的文本适合包装宽度;offsetLimit必须大于当前位置 -
requireNextWord- 如果是true,则当整个下一个单词不适合wrappingWidth返回的当前位置; 如果是false,则返回的偏移量至少比当前位置大1 - 结果
-
表示下一个
TextLayout限制的文本中的偏移量
-
nextLayout
public TextLayout nextLayout(float wrappingWidth)
返回下一个布局,并更新当前位置。- 参数
-
wrappingWidth- 下一个布局中文本允许的最大可见提前量 - 结果
-
a
TextLayout,从当前位置开始,代表wrappingWidth内的下一行
-
nextLayout
public TextLayout nextLayout(float wrappingWidth, int offsetLimit, boolean requireNextWord)
返回下一个布局,并更新当前位置。- 参数
-
wrappingWidth- 下一个布局中文本允许的最大可见提前量 -
offsetLimit- 第一个不能包含在下一个布局中的字符,即使限制后的文本适合包装宽度;offsetLimit必须大于当前位置 -
requireNextWord- 如果是true,并且如果当前位置的整个单词不适合包装宽度,则返回null。 如果是false,则返回有效布局,该布局至少包括当前位置的字符 - 结果
-
a
TextLayout,从当前位置开始,代表wrappingWidth内的下一行。 如果当前位置位于此LineBreakMeasurer使用的文本的LineBreakMeasurer,则返回null
-
getPosition
public int getPosition()
返回此LineBreakMeasurer的当前位置。- 结果
-
这个
LineBreakMeasurer的当前位置 - 另请参见:
-
setPosition(int)
-
setPosition
public void setPosition(int newPosition)
设置此LineBreakMeasurer的当前位置。- 参数
-
newPosition- 这个当前位置LineBreakMeasurer; 该位置应在用于构造此LineBreakMeasurer的文本内(或在最近传递给insertChar或deleteChar - 另请参见:
-
getPosition()
-
insertChar
public void insertChar(AttributedCharacterIterator newParagraph, int insertPos)
在将单个字符插入文本后更新此LineBreakMeasurer,并将当前位置设置为段落的开头。- 参数
-
newParagraph- 插入后的文本 -
insertPos- 文本中插入字符的位置 - 异常
-
IndexOutOfBoundsException- 如果insertPos小于newParagraph或大于或等于newParagraph -
NullPointerException- 如果newParagraph是null - 另请参见:
-
deleteChar(java.text.AttributedCharacterIterator, int)
-
deleteChar
public void deleteChar(AttributedCharacterIterator newParagraph, int deletePos)
从文本中删除单个字符后更新此LineBreakMeasurer,并将当前位置设置为段落的开头。- 参数
-
newParagraph- 删除后的文本 -
deletePos- 删除字符的文本中的位置 - 异常
-
IndexOutOfBoundsException-如果deletePos小于开始newParagraph或大于的端newParagraph -
NullPointerException- 如果newParagraph是null - 另请参见:
-
insertChar(java.text.AttributedCharacterIterator, int)
-
-