Swing/LeftClippedComboBox のバックアップ(No.21)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- Swing/LeftClippedComboBox へ行く。
- 1 (2007-06-19 (火) 17:35:29)
- 2 (2008-03-31 (月) 19:37:32)
- 3 (2008-04-01 (火) 22:22:35)
- 4 (2008-04-02 (水) 20:12:16)
- 5 (2008-09-30 (火) 15:36:45)
- 6 (2008-11-13 (木) 14:25:12)
- 7 (2009-11-09 (月) 20:21:54)
- 8 (2011-06-01 (水) 03:10:51)
- 9 (2013-02-05 (火) 17:27:26)
- 10 (2013-08-31 (土) 01:41:10)
- 11 (2014-11-25 (火) 03:03:31)
- 12 (2014-11-30 (日) 00:46:08)
- 13 (2015-02-22 (日) 21:02:43)
- 14 (2015-10-22 (木) 00:39:38)
- 15 (2016-05-27 (金) 15:33:39)
- 16 (2017-08-24 (木) 13:07:24)
- 17 (2017-11-02 (木) 15:28:23)
- 18 (2017-11-02 (木) 15:32:16)
- 19 (2018-02-24 (土) 19:51:30)
- 20 (2019-05-30 (木) 18:33:14)
- 21 (2021-02-18 (木) 06:53:27)
- category: swing
folder: LeftClippedComboBox
title: JComboBoxのアイテム文字列を左側からクリップ
tags: [JComboBox, ListCellRenderer, ArrowButton]
author: aterai
pubdate: 2007-06-18T19:09:42+09:00
description: JComboBoxのアイテム文字列がコンポーネントより長い場合、これを左側からクリップします。
image:
hreflang:
href: https://java-swing-tips.blogspot.com/2009/05/left-clipped-jcombobox.html lang: en
概要
JComboBox
のアイテム文字列がコンポーネントより長い場合、これを左側からクリップします。
Screenshot
Advertisement
サンプルコード
final JButton arrowButton = getArrowButton(combo02);
combo02.setRenderer(new DefaultListCellRenderer() {
@Override public Component getListCellRendererComponent(
JList list, Object value, int index,
boolean isSelected, boolean cellHasFocus) {
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
int itb = 0, ilr = 0;
Insets insets = getInsets();
itb += insets.top + insets.bottom;
ilr += insets.left + insets.right;
insets = combo02.getInsets();
itb += insets.top + insets.bottom;
ilr += insets.left + insets.right;
int availableWidth = combo02.getWidth() - ilr;
if (index < 0) {
//@see BasicComboBoxUI#rectangleForCurrentValue
int buttonSize = combo02.getHeight() - itb;
if (arrowButton != null) {
buttonSize = arrowButton.getWidth();
}
availableWidth -= buttonSize;
JTextField tf = (JTextField) combo02.getEditor().getEditorComponent();
insets = tf.getMargin();
availableWidth -= (insets.left + insets.right);
}
String cellText = (value != null) ? value.toString() : "";
//<blockquote cite="https://tips4java.wordpress.com/2008/11/12/left-dot-renderer/">
//@title Left Dot Renderer
//@auther Rob Camick
FontMetrics fm = getFontMetrics(getFont());
if (fm.stringWidth(cellText) > availableWidth) {
String dots = "...";
int textWidth = fm.stringWidth(dots);
int nChars = cellText.length() - 1;
while (nChars > 0) {
textWidth += fm.charWidth(cellText.charAt(nChars));
if (textWidth > availableWidth) break;
nChars--;
}
setText(dots + cellText.substring(nChars + 1));
}
//</blockquote>
return this;
}
});
View in GitHub: Java, Kotlin解説
- 標準の
JComboBox
が使用するDefaultListCellRenderer
はJLabel
を継承しているので、長い文字列は右側から省略される - 上記のサンプルでは左側から省略し、
...
で置き換えるようにセルレンダラーを変更- 長いファイル名でも拡張子は省略されない
- エディタ部分(
index < 0
の場合)を描画するときは、矢印ボタンの幅を考慮する必要がある LookAndFeel
によって余白などのサイズが微妙に異なる場合がある?- 補助文字(サロゲートペアなど)を含む文字列を扱う場合は、
String#charAt(int)
ではなく、String#codePointAt(int)
やCharacter.charCount(codePoint)
などを使用する必要があるFontMetrics fm = getFontMetrics(getFont()); if (fm.stringWidth(cellText) > availableWidth) { String dots = "..."; int textWidth = fm.stringWidth(dots); int len = cellText.length(); int[] acp = new int[cellText.codePointCount(0, len)]; int j = acp.length; for (int i = len; i > 0; i = cellText.offsetByCodePoints(i, -1)) { int cp = cellText.codePointBefore(i); textWidth += fm.charWidth(cp); if (textWidth > availableWidth) { break; } acp[--j] = cp; } setText(dots + new String(acp, j, acp.length - j)); }
参考リンク
- Swing - JTable - right align in cell even if the text is wider than the cell
- camickr さんが投稿(2005/06/10 5:52)した
JTable
でのサンプルがある
- camickr さんが投稿(2005/06/10 5:52)した
- Left Dot Renderer « Java Tips Weblog
- Java による Unicode サロゲートプログラミング