Java プラットフォーム 1.2

java.awt.font
クラス LineBreakMeasurer

java.lang.Object
  |
  +--java.awt.font.LineBreakMeasurer

public final class LineBreakMeasurer
extends Object

LineBreakMeasurer クラスを使用すれば、書式付きテキストを、特定の可視有効幅に収まる行 (またはセグメント) に分けることができます。これは、固有の幅 (ラッピング幅と呼ばれる) に収まるテキストの段落をクライアントに表示する場合に便利です。

LineBreakMeasurer は、書式付きテキストに対する反復子を使って構築されます。反復子の範囲はテキスト内の 1 つの段落です。LineBreakMeasurer は、次のテキストセグメントを開始するために、テキスト内の位置を格納します。最初は、この位置がテキストの始点です。段落の方向は、双方向フォーマット規則に従って、全方向 (左から右または右から左) に及びます。段落から取得されたすべてのセグメントは、その段落と同じ方向になります。

テキストのセグメントは、nextLayout メソッドを呼び出すことで取得されます。このメソッドは、ラッピング幅に収まるテキストを表す TextLayout を返します。nextLayout メソッドは、nextLayout が返したレイアウトの端に現在の位置を移動します。

LineBreakMeasurer は、もっとも一般的な次の改行を実装します。ラッピング幅に収まるすべての単語は、同じ行に配置されます。最初の単語が収まらなければ、ラッピング幅に収まるだけの文字がその行に配置されます。各行には少なくとも 1 文字が配置されます。

LineBreakMeasurer によって返される TextLayout のインスタンスは、タブを幅 0 のスペースと同様に扱います。位置決めのためにタブ区切りのセグメントを取得するクライアントは、テキストに対するリミットオフセットをとる nextLayout のオーバーロードを使うようにしてください。リミットオフセットは、タブ以降の最初の文字です。このメソッドが返す TextLayout オブジェクトは、指定されたリミット (現在の位置とリミットとの間のテキストがラッピング幅に収まらない場合には、リミットの前) で終わります。

タブ区切りのテキストをレイアウトするクライアントには、最初のセグメントを行に配置したあと、やや異なる改行ポリシーが必要です。残りの領域に一部の単語を収めるのではなく、全体を次の行に配置します。ポリシーのこの変更は、boolean パラメータをとる nextLayout のオーバーロードで要求できます。このパラメータが true の場合、nextLayout は、最初の単語が指定された領域に収まらないときに null を返します。下記のタブサンプルを参照してください。

通常、LineBreakMeasurer の作成に使用されたテキストが変更された場合は、変更を反映するために新しい LineBreakMeasurer を作成する必要があります (これまでの LineBreakMeasurer はそのまま正常に動作するが、テキストの変更には対応しない)。ただし、テキストの変更が 1 文字の挿入または削除の場合には、insertChar または deleteChar を呼び出して、既存の LineBreakMeasurer を「更新」してもかまいません。既存の LineBreakMeasurer を更新する方が、新しく作成するよりも処理時間がかかりません。ユーザのキー入力によってテキストを変更する場合は、これらの方法を利用するとよいでしょう。

:

コンポーネントに段落を描画します。

 public void paint(Graphics graphics) {

     Point2D pen = new Point2D(10, 20);

     // let styledText be an AttributedCharacterIterator containing at least
     // one character 

     LineBreakMeasurer measurer = new LineBreakMeasurer(styledText);
     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

コンストラクタの概要
LineBreakMeasurer(AttributedCharacterIterator text, BreakIterator breakIter, FontRenderContext frc)
          指定されたテキストに対する LineBreakMeasurer を構築します。
LineBreakMeasurer(AttributedCharacterIterator text, FontRenderContext frc)
          指定されたテキストに対する LineBreakMeasurer を構築します。
 
メソッドの概要
 void deleteChar(AttributedCharacterIterator newParagraph, int deletePos)
          テキストから文字が 1 つ削除されたあとに LineBreakMeasurer を更新します。
 int getPosition()
          LineBreakMeasurer の現在の位置を返します。
 void insertChar(AttributedCharacterIterator newParagraph, int insertPos)
          テキストに文字が 1 つ追加されたあとに LineBreakMeasurer を更新します。
 TextLayout nextLayout(float maxAdvance)
          次のレイアウトを返し、現在の位置を更新します。
 TextLayout nextLayout(float wrappingWidth, int offsetLimit, boolean requireNextWord)
          次のレイアウトを返し、現在の位置を更新します。
 int nextOffset(float maxAdvance)
          次のレイアウトの最後の位置を返します。
 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 - この LineBreakMeasurerTextLayout オブジェクトの生成対象とするテキスト。このテキストには、1 つ以上の文字が格納されていなければならない。text で得られるテキストが変更された場合、そのあとのこの LineBreakMeasurer のインスタンスへの呼び出しの結果は保証されない (ただし、あとで insertChar または deleteChar を呼び出す場合を除く。関連項目を参照)
frc - テキストの寸法を測る FontRenderContext
関連項目:
insertChar(java.text.AttributedCharacterIterator, int), deleteChar(java.text.AttributedCharacterIterator, int)

LineBreakMeasurer

public LineBreakMeasurer(AttributedCharacterIterator text,
                         BreakIterator breakIter,
                         FontRenderContext frc)
指定されたテキストに対する LineBreakMeasurer を構築します。
パラメータ:
text - この LineBreakMeasurerTextLayout オブジェクトの生成対象とするテキスト。このテキストには、1 つ以上の文字が格納されていなければならない。text で得られるテキストが変更された場合、その後のこの LineBreakMeasurer のインスタンスへの呼び出しの結果は、保証されない (ただし、あとで insertChar または deleteChar を呼び出す場合を除く。関連項目を参照)
breakIter - 改行を定義する BreakIterator
frc - テキストの寸法を測る FontRenderContext
関連項目:
insertChar(java.text.AttributedCharacterIterator, int), deleteChar(java.text.AttributedCharacterIterator, int)
メソッドの詳細

nextOffset

public int nextOffset(float maxAdvance)
次のレイアウトの最後の位置を返します。LineBreakMeasurer の現在の位置を更新しません。
パラメータ:
maxAdvance - 次のレイアウト内のテキストに許容される最大の可視有効幅
戻り値:
次の TextLayout のリミットを表すテキスト内のオフセット

nextOffset

public int nextOffset(float wrappingWidth,
                      int offsetLimit,
                      boolean requireNextWord)
次のレイアウトの最後の位置を返します。LineBreakMeasurer の現在の位置を更新しません。
パラメータ:
wrappingWidth - 次のレイアウト内のテキストに許容される最大の可視有効幅
offsetLimit - リミット以降のテキストがラッピング幅に収まる場合でも、次のレイアウトに含まれない最初の文字。offsetLimit は、現在の位置よりも大きくなければならない
requireNextWord - true の場合、次の単語全体が wrappingWidth に収まらないときに現在の位置が返される。false の場合、返されるオフセットは現在の位置よりも少なくとも 1 大きい
戻り値:
次の TextLayout のリミットを表すテキスト内のオフセット

nextLayout

public TextLayout nextLayout(float maxAdvance)
次のレイアウトを返し、現在の位置を更新します。
パラメータ:
maxAdvance - 次のレイアウト内のテキストに許容される最大の可視有効幅
戻り値:
maxAdvance に収まる次の行を表し、現在の位置から始まる TextLayout

nextLayout

public TextLayout nextLayout(float wrappingWidth,
                             int offsetLimit,
                             boolean requireNextWord)
次のレイアウトを返し、現在の位置を更新します。
パラメータ:
wrappingWidth - 次のレイアウト内のテキストに許容される最大の可視有効幅
offsetLimit - リミット以降のテキストがラッピング幅に収まる場合でも、次のレイアウトに含まれない最初の文字。offsetLimit は、現在の位置よりも大きくなければならない
requireNextWord - true の場合、かつ現在の位置にある単語全体がラッピング幅に収まらない場合、null が返される。false の場合、少なくとも現在の位置にある文字を含む、有効なレイアウトが返される
戻り値:
maxAdvance に収まる次の行を表し、現在の位置から始まる TextLayout。現在の位置が、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)
テキストに文字が 1 つ追加されたあとに LineBreakMeasurer を更新します。
パラメータ:
newParagraph - 追加後のテキスト
insertPos - テキスト内の、文字が追加された位置
関連項目:
deleteChar(java.text.AttributedCharacterIterator, int)

deleteChar

public void deleteChar(AttributedCharacterIterator newParagraph,
                       int deletePos)
テキストから文字が 1 つ削除されたあとに LineBreakMeasurer を更新します。
パラメータ:
newParagraph - 削除後のテキスト
deletePos - テキスト内の、文字が削除された位置
関連項目:
insertChar(java.text.AttributedCharacterIterator, int)

Java プラットフォーム 1.2

バグや機能要求の報告
新しい javadoc の表示についてのコメントやご提案
Java は、米国およびその他の国における米国 Sun Microsystems, Inc. の商標もしくは登録商標です。
Copyright 1993-1998 Sun Microsystems, Inc. 901 San Antonio Road,
Palo Alto, California, 94303, U.S.A. All Rights Reserved.