JavaTM 2 Platform
Standard Ed. 6

java.awt.font
類別 LineBreakMeasurer

java.lang.Object
  繼承者 java.awt.font.LineBreakMeasurer

public final class LineBreakMeasurer
extends Object

LineBreakMeasurer 類別允許將樣式化的文本斷為行(或段),以符合特定的可視 advance。這對希望顯示適合指定寬度(稱為環繞寬度)文本段落的客戶端很有用。

LineBreakMeasurer 通過樣式化文本上的迭代器建構。該迭代器的範圍應該是文本中的單個段落。LineBreakMeasurer 保存文本中用於開始下一個文本段的位置。最初,此位置是文本的開始點。根據雙向格式規則,為段落分派了總體方向(從左到右或從右到左)。從段落獲得的所有段具有與該段落相同的方向。

通過調用方法 nextLayout 可獲得文本的段,該方法會返回表示符合該環繞寬度的文本的 TextLayoutnextLayout 方法將當前位置移動到從 nextLayout 返回的佈局末尾。

LineBreakMeasurer 實作最常用的換行策略:在該行上放置符合環繞寬度的每一個詞。如果第一個詞不符合,那麼適合環繞寬度的所有字元將放置在該行上。每行至少放置一個字元。

LineBreakMeasurer 返回的 TextLayout 實例將 TAB 視為 0 寬度的空格。為了定位而希望獲得以 TAB 分界的段的客戶端應該重載 nextLayout,它可以在文本實行限制偏移量。限制偏移量應該是 TAB 後的第一個字元。從此方法返回的 TextLayout 物件在提供的界限處(或者界限之前,條件是當前位置和該界限之間的文本沒有完全位於環繞寬度之內)結束。

在行上放置首段之後,正在佈局 TAB 分隔文本的客戶端需要稍微不同的換行策略。新策略不是將部分詞放入剩餘空間,而是應該將無法完全放入剩餘空間的詞放在下一行。帶有 boolean 參數的 nextLayout 重載中可能請求這種策略更改。如果此參數為 true,且第一個詞無法放入給定的空間,則 nextLayout 返回 null。請參見下面的 TAB 範例。

通常,如果用於建構 LineBreakMeasurer 的文本發生更改,則必須建構新的 LineBreakMeasurer 以反映此更改。(原來的 LineBreakMeasurer 可繼續正常工作,但文本的更改對於它是未知的。)但是如果該文本更改是插入或刪除單個字元,則可通過調用 insertChardeleteChar 來“更新”現有的 LineBreakMeasurer。更新現有的 LineBreakMeasurer 比創建一個新 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();
     }
 }
 

使用 TAB 呈現文本。為簡單起見,假定總體的文本方向為從左到右

 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, BreakIterator breakIter, FontRenderContext frc)
          為指定的文本建構一個 LineBreakMeasurer
LineBreakMeasurer(AttributedCharacterIterator text, FontRenderContext frc)
          為指定的文本建構一個 LineBreakMeasurer
 
方法摘要
 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 的當前位置。
 
從類別 java.lang.Object 繼承的方法
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

建構子詳細資訊

LineBreakMeasurer

public LineBreakMeasurer(AttributedCharacterIterator text,
                         FontRenderContext frc)
為指定的文本建構一個 LineBreakMeasurer

參數:
text - 此 LineBreakMeasurer 為其產生 TextLayout 物件的文本;該文本必須至少包含一個字元;如果通過 iter 提供的文本發生更改,則再次調用此 LineBreakMeasurer 實例是不明確的(後來調用 insertChardeleteChar 等某些情況除外 - 參見下面內容)
frc - 套件含關於正確測量文本所需的圖形設備的資訊;由於設備分辨率和屬性(抗鋸齒)的不同,文本測量可能稍有變化;此參數不指定 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 實例是不明確的(後來調用 insertChardeleteChar 等某些情況除外 - 參見下面內容)
breakIter - 定義換行的 BreakIterator
frc - 套件含關於正確測量文本所需的圖形設備的資訊;由於設備分辨率和屬性(抗鋸齒)的不同,文本測量可能稍有變化;此參數不指定 LineBreakMeasurer 和使用者空間之間的轉換
拋出:
IllegalArgumentException - 如果文本少於一個字元
另請參見:
insertChar(java.text.AttributedCharacterIterator, int), deleteChar(java.text.AttributedCharacterIterator, int)
方法詳細資訊

nextOffset

public int nextOffset(float wrappingWidth)
返回下一個佈局結尾處的位置。不更新此 LineBreakMeasurer 的當前位置。

參數:
wrappingWidth - 下一佈局中文本所允許的最大可視 advance
返回:
文本中表示下一個 TextLayout 限制的偏移量。

nextOffset

public int nextOffset(float wrappingWidth,
                      int offsetLimit,
                      boolean requireNextWord)
返回下一個佈局結尾處的位置。不更新此 LineBreakMeasurer 的當前位置。

參數:
wrappingWidth - 下一佈局中文本所允許的最大可視 advance
offsetLimit - 即使限制後的文本適合該環繞寬度,下一個佈局中也無法包括的第一個字元;offsetLimit 必須大於當前位置
requireNextWord - 如果為 true,且下一個詞的全部不適合 wrappingWidth,則為返回的當前位置;如果為 false,則返回的偏移量至少比當前位置大一
返回:
文本中表示下一個 TextLayout 限制的偏移量。

nextLayout

public TextLayout nextLayout(float wrappingWidth)
返回下一個佈局,並更新當前位置。

參數:
wrappingWidth - 下一佈局中文本所允許的最大可視 advance
返回:
從當前位置開始的 TextLayout,它表示適合 wrappingWidth 的下一行。

nextLayout

public TextLayout nextLayout(float wrappingWidth,
                             int offsetLimit,
                             boolean requireNextWord)
返回下一個佈局,並更新當前位置。

參數:
wrappingWidth - 下一個佈局中文本所允許的最大可視 advance
offsetLimit - 即使限制後的文本適合環繞寬度,下一個佈局中也無法包括的第一個字元;offsetLimit 必須大於當前位置
requireNextWord - 如果為 true,並且當前位置的整個詞不適合環繞寬度,則返回 null。如果為 false,則返回有效的佈局,該佈局至少包括當前位置的字元
返回:
從當前位置開始的 TextLayout,它表示適合 wrappingWidth 的下一行。如果當前位置位於由此 LineBreakMeasurer 使用的文本末尾處,則返回 null

getPosition

public int getPosition()
返回此 LineBreakMeasurer 的當前位置。

返回:
LineBreakMeasurer 的當前位置
另請參見:
setPosition(int)

setPosition

public void setPosition(int newPosition)
設置此 LineBreakMeasurer 的當前位置。

參數:
newPosition - 此 LineBreakMeasurer 的當前位置;該位置應位於建構此 LineBreakMeasurer 所使用的文本內(或位於最近傳遞給 insertChardeleteChar 的文本內)
另請參見:
getPosition()

insertChar

public void insertChar(AttributedCharacterIterator newParagraph,
                       int insertPos)
將單個字元插入文本後,更新此 LineBreakMeasurer,並將當前位置設置為段落的開始。

參數:
newParagraph - 插入後的文本
insertPos - 文本中插入字元的位置
拋出:
IndexOutOfBoundsException - 如果 insertPos 小於 newParagraph 的開始,或者大於或等於 newParagraph 的末尾
NullPointerException - 如果 newParagraphnull
另請參見:
deleteChar(java.text.AttributedCharacterIterator, int)

deleteChar

public void deleteChar(AttributedCharacterIterator newParagraph,
                       int deletePos)
從文本刪除單個字元之後,更新此 LineBreakMeasurer,並將當前位置設置為段落的開始。

參數:
newParagraph - 刪除之後的文本
deletePos - 文本中刪除字元的位置
拋出:
IndexOutOfBoundsException - 如果 deletePos 小於 newParagraph 的開始,或大於 newParagraph 的末尾
NullPointerException - 如果 newParagraphnull
另請參見:
insertChar(java.text.AttributedCharacterIterator, int)

JavaTM 2 Platform
Standard Ed. 6

提交錯誤或意見

版權所有 2008 Sun Microsystems, Inc. 保留所有權利。請遵守GNU General Public License, version 2 only