http://www.ne.jp/asahi/hishidama/home/tech/java/swing/JLabel.html
JLabel等の文字列の省略
JLabelやJComboBoxなどで表示されている文字列がコンポーネントのサイズを超えると、文字列の最後が「...」になって省略される。
これは、BasicLabelUI#layoutCL() から SwingUtilities.layoutCompoundLabel() を呼び出して、省略した文字列の取得や表示座標を計算している。
省略文字列を変更する
JLabelやJComboboxの省略文字を変更するにはオリジナルのLabelUIを作成して省略文字の処理を変更する
サンプル
以下は、文字列の最後ではなく、途中を省略するサンプル。
真ん中の左右の文字列の幅は、プロポーショナルフォントを考慮して、バイナリサーチで計算する。
1 |
class MetalLabelUIForMiddleClip extends MetalLabelUI {
protected String layoutCL(
JLabel label,
FontMetrics fontMetrics,
String text,
Icon icon,
Rectangle viewR,
Rectangle iconR,
Rectangle textR)
{
String clipString = "...";
int clipLength = clipString.length();
int clipWidth = fontMetrics.stringWidth(clipString);
int width = viewR.width - viewR.x;
if (icon != null){
width = width - (icon.getIconWidth() + label.getIconTextGap());
}
// 超える可能性あり
if (fontMetrics.stringWidth(text) > width ){
// System.out.println(viewR);
// System.out.println(iconR);
// System.out.println(icon.getIconWidth());
// System.out.println(label.getIconTextGap());
int middleWidth = (width - clipWidth ) / 2;
int length = text.length();
int middle = length / 2;
String left = text.substring(0, middle);
left = cutString(left, fontMetrics, middleWidth);
String right = text.substring(middle, length);
StringBuilder sb = new StringBuilder(right);
;
right = sb.reverse().toString();
right = cutString(right, fontMetrics, middleWidth);
sb.delete(0, sb.length());
right = sb.append(right).reverse().toString();
sb.delete(0, sb.length());
sb.append(left).append("...").append(right);
// System.out.println(left);
// System.out.println(right);
text = sb.toString();
}
// System.out.println(text);
return SwingUtilities.layoutCompoundLabel(
(JComponent) label,
fontMetrics,
text,
icon,
label.getVerticalAlignment(),
label.getHorizontalAlignment(),
label.getVerticalTextPosition(),
label.getHorizontalTextPosition(),
viewR,
iconR,
textR,
label.getIconTextGap());
}
protected String cutString(String text, FontMetrics fm, int width){
if (width <= 0){
return "";
}
if (fm.stringWidth(text) <= width){
return text;
}
int left = 0;
int right = text.length();
int middle = 0;
while(right - left > 1){
middle = left + (right - left) / 2;
if (fm.stringWidth(text.substring(0, middle)) > width){
right = middle;
} else {
left = middle;
}
}
// 最後の2つのどちらか
if (fm.stringWidth(text.substring(0, right)) > width){
right = left;
}
return text.substring(0, right);
}
} |
このLabelUIを使うには
JLabelの場合
JLabel test = new JLabel("aaaaaaaaaaaaaaaaaaaaaaaaaaaa");
test.setUI(new MetalLabelUIForMiddleClip ());
JComboBoxの場合
JComboBox cb = new JComboBox(new Object[]{"aaaaaaaaaaaaaaaa"});
ListCellRenderer renderer = cb.getRenderer();
if (!(renderer instanceof JLabel)){
return;
}
LabelUI labelui = ((JLabel)renderer).getUI();
if (!MetalLabelUI.class.equals(labelui.getClass())){
return;
}
((JLabel)renderer).setUI(new MetalLabelUIForMiddleClip());
[カテゴリ: プログラミング言語 > Java]
[通知用URL]
Tweet
最終更新時間:2014年11月12日 22時41分40秒