長いテキストコンテンツがあり、または他の何かを使用して位置合わせを正当化して画面に表示したいと思います。現在、右/左/中央揃えはできますが、位置合わせを正当化するLabelField
ことはできません。
これを行うのに役立つカスタムコントロールはありますか?
長いテキストコンテンツがあり、または他の何かを使用して位置合わせを正当化して画面に表示したいと思います。現在、右/左/中央揃えはできますが、位置合わせを正当化するLabelField
ことはできません。
これを行うのに役立つカスタムコントロールはありますか?
これは単なるプロトタイプであるため、処理できないものがある可能性があります。しかし、それはあなたがやりたいことをするために使うことができる出発点であるべきです。重要なロジックのほとんどはpaint()
メソッドにあります。
これを行うための組み込み(RIMライブラリ)の方法を私は知りません。
public class JustifiedLabelField extends LabelField {
/** a cache of the label's words, to avoid having to recalculate every
time paint() is called */
private String[] _words;
/** the dynamic field height */
private int _height = 0;
public JustifiedLabelField(Object text, long style){
super(text, style);
setText(text);
}
public void setText(Object text) {
// update the words cache when text changes
_words = split((String)text, " "); // NOTE: this only supports String type!
super.setText(text);
}
public int getPreferredHeight() {
// I believe overriding this method is necessary because the
// justification might produce a different total number of lines,
// depending on the algorithm used
return (_height > 0) ? _height : super.getPreferredHeight();
}
protected void paint(Graphics g) {
Font font = g.getFont();
int space = font.getAdvance(' ');
int fontHeight = font.getHeight();
int fieldWidth = getWidth();
int word = 0;
int y = 0;
while (word < _words.length) {
// each iteration of this loop handles one line
int wordsInLine = 0;
int lineWordWidths = 0;
// first loop over all words that fit on this line, to measure
while (word < _words.length) {
int wordWidth = font.getAdvance(_words[word]);
if (lineWordWidths + wordWidth <= fieldWidth) {
lineWordWidths += (wordWidth + space);
word++;
wordsInLine++;
} else {
break;
}
}
// how much total space (gap) should be placed between every two words?
int gapSpacing = 0;
if (word == _words.length) {
// don't justify at all on last line
gapSpacing = space;
} else if (wordsInLine != 1) {
gapSpacing = (fieldWidth - (lineWordWidths - wordsInLine * space)) / (wordsInLine - 1);
}
int x = 0;
// now actually draw the words, with added spacing
for (int j = word - wordsInLine; j < word; j++) {
int span = g.drawText(_words[j], x, y);
x += span + gapSpacing;
}
y += fontHeight;
}
_height = y;
}
}
上記のコードはString
split()
メソッドを利用しています。ここで1つの可能な実装を見つけることができます。
次に、次のようなクラスを使用します。
public LabelScreen() {
super(MainScreen.VERTICAL_SCROLL | MainScreen.VERTICAL_SCROLLBAR);
String loremIpsum = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nam cursus. Morbi ut mi. Nullam enim leo, egestas id, condimentum at, laoreet mattis, massa. Sed eleifend nonummy diam. Praesent mauris ante, elementum et, bibendum at, posuere sit amet, nibh. Duis tincidunt lectus quis dui viverra vestibulum. Suspendisse vulputate aliquam dui. Nulla elementum dui ut augue. Aliquam vehicula mi at mauris. Maecenas placerat, nisl at consequat rhoncus, sem nunc gravida justo, quis eleifend arcu velit quis lacus. Morbi magna magna, tincidunt a, mattis non, imperdiet vitae, tellus. Sed odio est, auctor ac, sollicitudin in, consequat vitae, orci. Fusce id felis. Vivamus sollicitudin metus eget eros.";
JustifiedLabelField label = new JustifiedLabelField(loremIpsum, Field.NON_FOCUSABLE);
add(label);
}
これを生成する:
LabelField
setText()
だけでなく、他のタイプでまたはコンストラクターを呼び出すことができますString
。私のクラスはをサポートしているだけString
ですが、それを簡単に拡張できます。' '
)でのみ分割します。他の文字の分割をサポートしたり、ダッシュを挿入して非常に長い単語を分割したりすることもできます。それはあなたにお任せします。split()
上に投稿したコードを少し改良して、ここにオンラインで投稿しました。新しいバージョンはパディングを処理する必要がありますが、このバージョンは処理しません。LabelField
スーパークラスがフィールドに必要と考える行数を変更する文字列分割アルゴリズムを選択した場合も、垂直方向のサイズの問題を処理する必要があります。その他のコメントも。