|
JavaTM 2 Platform Std. Ed. v1.4.0 |
||||||||||
| 前のクラス 次のクラス | フレームあり フレームなし | ||||||||||
| 概要: 入れ子 | フィールド | コンストラクタ | メソッド | 詳細: フィールド | コンストラクタ | メソッド | ||||||||||
java.lang.Object | +--java.awt.font.LineBreakMeasurer
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);
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| コンストラクタの概要 | |
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 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 |
| コンストラクタの詳細 |
public LineBreakMeasurer(AttributedCharacterIterator text,
FontRenderContext frc)
LineBreakMeasurer を構築します。
text - この LineBreakMeasurer が TextLayout オブジェクトの生成対象とするテキスト。このテキストには、1 つ以上の文字が格納されていなければならない。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 オブジェクトの生成対象とするテキスト。このテキストには、1 つ以上の文字が格納されていなければならない。iter で得られるテキストが変更された場合、その後のこの LineBreakMeasurer のインスタンスへの呼び出しの結果は、保証されない (ただし、あとで insertChar または deleteChar を呼び出す場合を除く。関連項目を参照)breakIter - 改行を定義する BreakIteratorfrc - テキストを正確に測定するために必要なグラフィックスデバイスに関する情報がある。テキスト測定は、デバイスの解像度によりわずかに異なり、アンチエイリアスのような属性によっても異なる。このパラメータは、LineBreakMeasurer とユーザ空間の間の移動は指定しない
IllegalArgumentException - テキストが 1 文字に満たない場合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 の場合、返される座標は現在の位置よりも少なくとも 1 大きい
TextLayout のリミットを表すテキスト内の座標public TextLayout nextLayout(float wrappingWidth)
wrappingWidth - 次のレイアウト内のテキストに許容される最大の可視有効幅
wrappingWidth に収まる次の行を表し、現在の位置から始まる TextLayout
public TextLayout nextLayout(float wrappingWidth,
int offsetLimit,
boolean requireNextWord)
wrappingWidth - 次のレイアウト内のテキストに許容される最大の可視有効幅offsetLimit - リミット以降のテキストがラッピング幅に収まる場合でも、次のレイアウトに含まれない最初の文字。offsetLimit は、現在の位置よりも大きくなければならないrequireNextWord - true の場合、かつ現在の位置にある単語全体がラッピング幅に収まらない場合、null が返される。false の場合、少なくとも現在の位置にある文字を含む、有効なレイアウトが返される
wrappingWidth に収まる次の行を表し、現在の位置から始まる TextLayout。現在の位置が、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 を更新して、現在の位置をその段落の先頭に設定します。
newParagraph - 削除後のテキストdeletePos - テキスト内の、文字が削除された位置
IndexOutOfBoundsException - deletePos が newParagraph の開始位置より前、または newParagraph の終了位置より後ろである場合
NullPointerException - newParagraph が null の場合insertChar(java.text.AttributedCharacterIterator, int)
|
JavaTM 2 Platform Std. Ed. v1.4.0 |
||||||||||
| 前のクラス 次のクラス | フレームあり フレームなし | ||||||||||
| 概要: 入れ子 | フィールド | コンストラクタ | メソッド | 詳細: フィールド | コンストラクタ | メソッド | ||||||||||
Java、Java 2D、および JDBC は米国ならびにその他の国における米国 Sun Microsystems, Inc. の商標もしくは登録商標です。
Copyright 1993-2002 Sun Microsystems, Inc. 901 San Antonio Road
Palo Alto, California, 94303, U.S.A. All Rights Reserved.