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继续正常工作,但不会意识到文字的更改。)然而,如果文字更改是插入或删除单个字符,现有的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后更新此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调用insertChar或deleteChar时,请参见下文) 
           frc - 包含有关正确测量文本所需的图形设备信息; 
            文本测量可能会因设备分辨率和抗锯齿等属性而略有不同。 
            此参数不指定LineBreakMeasurer与用户空间之间的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调用insertChar或deleteChar时,请参见下文) 
           breakIter - 定义换行符的BreakIterator 
           frc - 包含有关正确测量文本所需的图形设备信息; 
            文本测量可能会因设备分辨率和抗锯齿等属性而略有不同。 
            该参数不指定LineBreakMeasurer与用户空间之间的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使用的文本的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 -如果 
            insertPos小于开始 
            newParagraph ,或者大于或等于的端 
            newParagraph 
           NullPointerException - 如果 
            newParagraph是 
            null 
           deleteChar(java.text.AttributedCharacterIterator, int) 
           public void deleteChar(AttributedCharacterIterator newParagraph, int deletePos)
LineBreakMeasurer后,更新此 
           LineBreakMeasurer ,并将当前位置设置为段落的开头。 
          newParagraph - 删除后的文字 
           deletePos - 字符被删除的文本中的位置 
           IndexOutOfBoundsException -如果 
            deletePos小于开始 
            newParagraph或大于的端 
            newParagraph 
           NullPointerException - 如果 
            newParagraph是 
            null 
           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.