public final class LineBreakMeasurer extends Object
LineBreakMeasurer
类允许样式文本被分解成线(或段),适合在一个特定的视觉发展。这为客户谁想要显示一段文字,适合一个特定的宽度范围内是有用的,称为
包边宽度。
LineBreakMeasurer
与样式文本迭代器构造。迭代器的范围应该是文本中的一个段落。LineBreakMeasurer
保持文本的位置为下一段的开始。最初,这个位置是文本的开始。根据双向格式规则,段落被分配一个整体方向(左到右或右向左)。从段落获得的所有片段与段落有相同的方向。
通过调用该方法nextLayout
得到文本段,它返回一个TextLayout
表示适合在包边宽度的文本。的nextLayout
方法把当前位置移到布局结束返回nextLayout
。
LineBreakMeasurer
实现最常用的线打破政策:每一个字,适合包装宽度内放置就行了。如果第一个字不适合,那么所有的字符,适合在包装宽度放在线。至少一个字符被放置在每一行上。
的TextLayout
实例返回LineBreakMeasurer
对待标签像0-width空间。客户希望获得制表符分隔段的定位应使用nextLayout
以限制在文本偏移超载。限制偏移量应该是标签后的第一个字符。此方法返回的对象TextLayout
端在规定(或之前,如果当前位置和极限之间的文本不适合完全在包边宽度)。
正在铺设制表符分隔的文本的客户需要在第一个段被放置在一行之后,需要一个稍微不同的行断策略。在其余的空间中,而不是拟合部分的话,他们应该放置不适合在剩余的空间完全在下一行的话。这一政策的改变可以在nextLayout
以boolean
参数过载要求。如果这个参数是true
,nextLayout
返回null
如果第一句不适合给定的空间。见下面的标签示例。
一般来说,如果用于构建LineBreakMeasurer
变化的文本,一种新的LineBreakMeasurer
必须建立反映变化。(老LineBreakMeasurer
继续正常工作,但它不会意识到文本改变。)然而,如果文本是一个字符的插入或缺失,现有的LineBreakMeasurer
可以通过调用insertChar
或deleteChar
更新,更新现有的LineBreakMeasurer
比创造一个新的快得多。基于用户键入的修改文本的客户端应该利用这些方法。
实例:
在组件中渲染一个段落
public void paint(Graphics graphics) { Point2D pen = new Point2D(10, 20); Graphics2D g2d = (Graphics2D)graphics; FontRenderContext frc = g2d.getFontRenderContext(); // let styledText be an AttributedCharacterIterator containing at least // one character LineBreakMeasurer measurer = new LineBreakMeasurer(styledText, frc); float wrappingWidth = getSize().width - 15; while (measurer.getPosition() < fStyledText.length()) { TextLayout layout = measurer.nextLayout(wrappingWidth); pen.y += (layout.getAscent()); float dx = layout.isLeftToRight() ? 0 : (wrappingWidth - layout.getAdvance()); layout.draw(graphics, pen.x + dx, pen.y); pen.y += 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 and Description |
---|
LineBreakMeasurer(AttributedCharacterIterator text, BreakIterator breakIter, FontRenderContext frc)
构建了一个指定的文本
LineBreakMeasurer 。
|
LineBreakMeasurer(AttributedCharacterIterator text, FontRenderContext frc)
构建了一个指定的文本
LineBreakMeasurer 。
|
Modifier and Type | Method and Description |
---|---|
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 当前位置。
|
public LineBreakMeasurer(AttributedCharacterIterator text, FontRenderContext frc)
LineBreakMeasurer
。
text
-这
LineBreakMeasurer
产生
TextLayout
对象的文本;文本必须至少包含一个字符;如果可以通过
iter
变化的文本,再调用此
LineBreakMeasurer
实例是不确定的(但在一些情况下,当
insertChar
或
deleteChar
调用之后-见下文)
frc
-包含一个图形设备,需要正确衡量文本信息;文本的测量可以略有不同的设备分辨率不同,属性如抗锯齿;这个参数没有指定
LineBreakMeasurer
和用户空间之间的翻译
insertChar(java.text.AttributedCharacterIterator, int)
,
deleteChar(java.text.AttributedCharacterIterator, int)
public LineBreakMeasurer(AttributedCharacterIterator text, BreakIterator breakIter, FontRenderContext frc)
LineBreakMeasurer
。
text
-这
LineBreakMeasurer
产生
TextLayout
对象的文本;文本必须至少包含一个字符;如果可以通过
iter
变化的文本,再调用此
LineBreakMeasurer
实例是不确定的(但在一些情况下,当
insertChar
或
deleteChar
调用之后-见下文)
breakIter
-定义
BreakIterator
换行
frc
-包含一个图形设备,需要正确衡量文本信息;文本的测量可以略有不同的设备分辨率不同,属性如抗锯齿;这个参数没有指定
LineBreakMeasurer
和用户空间之间的翻译
IllegalArgumentException
-如果文本已经小于一个字符
insertChar(java.text.AttributedCharacterIterator, int)
,
deleteChar(java.text.AttributedCharacterIterator, int)
public int nextOffset(float wrappingWidth)
LineBreakMeasurer
当前位置。
wrappingWidth
-在未来布局文本允许的最大可见的进展
TextLayout
极限文本偏移。
public int nextOffset(float wrappingWidth, int offsetLimit, boolean requireNextWord)
LineBreakMeasurer
当前位置。
wrappingWidth
-在未来布局文本允许的最大可见的进展
offsetLimit
-第一个字符,不能包含在未来的布局,即使限制后的文本将符合包装宽度;
offsetLimit
必须大于当前位置
requireNextWord
-如果
true
,当前位置,如果整个一词不符合
wrappingWidth
返回;如果
false
,偏移量返回至少有一个大于当前位置
TextLayout
极限文本偏移
public TextLayout nextLayout(float wrappingWidth)
wrappingWidth
-在未来布局文本允许的最大可见的进展
TextLayout
,从当前位置开始,这是在
wrappingWidth
下直线拟合
public TextLayout nextLayout(float wrappingWidth, int offsetLimit, boolean requireNextWord)
wrappingWidth
-在未来布局文本允许的最大可见的进展
offsetLimit
-第一个字符,不能包含在未来的布局,即使限制后的文本将符合包装宽度;
offsetLimit
必须大于当前位置
requireNextWord
-如果
true
,如果当前位置的整个词不符合包装的宽度,
null
返回。如果
false
,有效的布局还包括至少在当前位置的字符
TextLayout
,从当前位置开始,表示在
wrappingWidth
下直线拟合。如果当前位置是在这个
LineBreakMeasurer
使用文本的结束,
null
返回
public int getPosition()
LineBreakMeasurer
当前位置。
LineBreakMeasurer
当前位置
setPosition(int)
public void setPosition(int newPosition)
LineBreakMeasurer
当前位置。
newPosition
-这
LineBreakMeasurer
当前位置;位置应在用于构建这
LineBreakMeasurer
文本(或文本最近通过
insertChar
或
deleteChar
getPosition()
public void insertChar(AttributedCharacterIterator newParagraph, int insertPos)
LineBreakMeasurer
更新后一个字符插入文本,并设置段落的开头的当前位置。
newParagraph
后插入文本
insertPos
-位置在文本中所插入的字符
IndexOutOfBoundsException
-如果
newParagraph
insertPos
小于或大于或等于
newParagraph
结束的开始
null
newParagraph
NullPointerException
deleteChar(java.text.AttributedCharacterIterator, int)
public void deleteChar(AttributedCharacterIterator newParagraph, int deletePos)
LineBreakMeasurer
更新后一个字符是从文本中删除,并设置段落的开头的当前位置。
newParagraph
后删除文本
deletePos
-位置在文本的字符被删除
IndexOutOfBoundsException
-如果
deletePos
小于或大于
newParagraph
newParagraph
结束的开始
null
newParagraph
NullPointerException
insertChar(java.text.AttributedCharacterIterator, int)
Submit a bug or feature
For further API reference and developer documentation, see Java SE Documentation. That documentation contains more detailed, developer-targeted descriptions, with conceptual overviews, definitions of terms, workarounds, and working code examples.
Copyright © 1993, 2014, Oracle and/or its affiliates. All rights reserved.