- java.lang.Object
-
- java.awt.font.LineBreakMeasurer
-
public final class LineBreakMeasurer extends Object
LineBreakMeasurer类允许将样式文本分解成符合特定视觉进步的线(或段)。 这对于希望显示适合特定宽度的文本段(称为包装宽度)的客户端是有用的。LineBreakMeasurer用样式文本的迭代器构造。 迭代器的范围应该是文本中的一个段落。LineBreakMeasurer在文本中保留开始下一个文本段的位置。 最初,这个位置是文本的开始。 根据双向格式规则,段落被分配一个整体方向(从左到右或从右到左)。 从段落获得的所有分段具有与段落相同的方向。通过调用方法
nextLayout获得文本段,该方法返回表示适合包装宽度的文本的TextLayout。nextLayout方法将当前位置移动到从nextLayout返回的布局的nextLayout。LineBreakMeasurer实现了最常用的划线策略:适合包装宽度的每个单词都放在行上。 如果第一个字不适合,那么适合包装宽度的所有字符都放在行上。 每条线上至少放置一个字符。TextLayout返回的TextLayout实例LineBreakMeasurer标签视为0宽度的空格。 希望获取制表符分隔段以进行定位的客户端应使用nextLayout的超负荷,该超负荷在nextLayout中进行了限制。 限制偏移应该是标签后的第一个字符。 从此方法返回的TextLayout对象以提供的限制结束(或之前,如果当前位置和限制之间的文本将完全不适合包装宽度)。布局制表符分隔文本的客户在第一个细分受众群放在一行之后,需要略有不同的破产政策。 不要在剩余空间中拟合部分单词,而应将下一行中不完整的单词放在剩余空间中。 可以在
nextLayout的过载中请求此策略的更改,该参数需要boolean参数。 如果此参数为true,如果第一个字不适合给定的空间,则nextLayout返回null。 请参阅下面的选项卡示例。一般来说,如果用于构建
LineBreakMeasurer的文本发生更改,LineBreakMeasurer必须构建新的LineBreakMeasurer以反映更改。 (旧的LineBreakMeasurer继续正常工作,但不会意识到文本的更改。)然而,如果文本更改是插入或删除单个字符,现有的LineBreakMeasurer可以通过调用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
-
-
构造方法摘要
构造方法 Constructor 描述 LineBreakMeasurer(AttributedCharacterIterator text, FontRenderContext frc)为指定的文本构造一个LineBreakMeasurer。LineBreakMeasurer(AttributedCharacterIterator text, BreakIterator breakIter, FontRenderContext frc)为指定的文本构造一个LineBreakMeasurer。
-
方法摘要
所有方法 接口方法 具体的方法 Modifier and Type 方法 描述 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,返回的偏移量至少比当前位置大一个 - 结果
-
文字中的偏移量代表下一个
TextLayout的限制
-
nextLayout
public TextLayout nextLayout(float wrappingWidth)
返回下一个布局,并更新当前位置。- 参数
-
wrappingWidth- 下一个布局文本允许的最大可见提前 - 结果
-
一个
TextLayout,从当前位置开始,代表下一行拟合wrappingWidth
-
nextLayout
public TextLayout nextLayout(float wrappingWidth, int offsetLimit, boolean requireNextWord)
返回下一个布局,并更新当前位置。- 参数
-
wrappingWidth- 下一个布局文本允许的最大可见提前 -
offsetLimit- 下一个布局中不能包含的第一个字符,即使限制后的文本也适合包装宽度;offsetLimit必须大于当前位置 -
requireNextWord- 如果是true,如果当前位置的整个字不适合包装宽度,则返回null。 如果是false,则返回一个至少包含当前位置字符的有效布局 - 结果
-
一个
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)
-
-