JComboBoxで文字列が溢れる場合はJToolTipを表示可能にする
Total: 1747
, Today: 3
, Yesterday: 0
Posted by aterai at
Last-modified:
概要
JComboBox
のアイテム文字列がJComboBox
本体またはドロップダウンリストのセルから溢れる場合のみJToolTip
を表示可能に設定します。
Screenshot
Advertisement
サンプルコード
private static <E> JComboBox<E> makeComboBox(ComboBoxModel<E> model) {
return new JComboBox<E>(model) {
@Override public void updateUI() {
setRenderer(null);
super.updateUI();
ListCellRenderer<? super E> renderer = getRenderer();
JComboBox<E> combo = this;
JButton arrowButton = getArrowButton(this);
setRenderer((list, value, index, isSelected, cellHasFocus) -> {
Component r = renderer.getListCellRendererComponent(
list, value, index, isSelected, cellHasFocus);
JComponent c = (JComponent) r;
// Insets i1 = combo.getInsets();
Insets ins = c.getInsets();
// int availableWidth = combo.getWidth() - i1.top - i1.bottom - ins.top - ins.bottom;
Rectangle rect = SwingUtilities.calculateInnerArea(combo, null);
// System.out.println(rect);
int availableWidth = rect.width - ins.top - ins.bottom;
String str = Objects.toString(value, "");
FontMetrics fm = c.getFontMetrics(c.getFont());
c.setToolTipText(fm.stringWidth(str) > availableWidth ? str : null);
if (index < 0) {
// @see BasicComboBoxUI#rectangleForCurrentValue
// System.out.println(UIManager.getBoolean("ComboBox.squareButton"));
// int buttonSize = combo.getHeight() - i1.top - i1.bottom; // - ins.top - ins.bottom;
int buttonSize = Objects.nonNull(arrowButton) ? arrowButton.getWidth() : rect.height;
availableWidth -= buttonSize;
JTextField tf = (JTextField) combo.getEditor().getEditorComponent();
availableWidth -= tf.getMargin().left + tf.getMargin().right;
combo.setToolTipText(fm.stringWidth(str) > availableWidth ? str : null);
}
return c;
});
}
private JButton getArrowButton(Container combo) {
for (Component c: combo.getComponents()) {
if (c instanceof JButton) {
return (JButton) c;
}
}
return null;
}
};
}
View in GitHub: Java, Kotlin解説
上記のサンプルでは、JComboBox
の本体またはドロップダウンリストで文字列の溢れが発生する場合のみJToolTip
を表示するようListCellRenderer
を設定しています。
JComboBox
のドロップダウンリストJComboBox
の内部ペイント領域の幅からセルレンダラーのインセットを引いた長さよりアイテム文字列の幅が短い場合に溢れが発生するので、レンダラーにsetToolTipText(...)
メソッドで省略前のアイテム文字列をツールチップ文字列として設定
JComboBox
の本体:JComboBox
の内部ペイント領域の幅からセルレンダラーのインセット、ArrowButton
の幅、EditorComponent
のインセットを引いた長さよりアイテム文字列の幅が短い場合に溢れが発生するので、JComboBox
本体にsetToolTipText(...)
メソッドで省略前のアイテム文字列をツールチップ文字列として設定ArrowButton
の幅はUIManager.getBoolean("ComboBox.squareButton")
がtrue
で正方形になる場合はJComboBox
の高さから取得可能だが、このサンプルではJComboBox
の子JButton
を検索して直接その幅を取得している
参考リンク
- JComboBoxの各アイテムやArrowButtonにそれぞれToolTipTextを設定する
- JComboBoxのアイテム文字列を左側からクリップ
- java - JComboBox with tooltip if display area too small, while maintaining look and feel - Stack Overflow