- 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 方法 描述 void
deleteChar(AttributedCharacterIterator newParagraph, int deletePos)
从文本中删除单个字符后,更新此LineBreakMeasurer
,并将当前位置设置为段落的开头。int
getPosition()
返回此LineBreakMeasurer
的当前位置。void
insertChar(AttributedCharacterIterator newParagraph, int insertPos)
在将单个字符插入到文本中后,更新此LineBreakMeasurer
,并将当前位置设置为段落的开头。TextLayout
nextLayout(float wrappingWidth)
返回下一个布局,并更新当前位置。TextLayout
nextLayout(float wrappingWidth, int offsetLimit, boolean requireNextWord)
返回下一个布局,并更新当前位置。int
nextOffset(float wrappingWidth)
返回下一个布局末尾的位置。int
nextOffset(float wrappingWidth, int offsetLimit, boolean requireNextWord)
返回下一个布局末尾的位置。void
setPosition(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)
-
-