Swing/ComboBoxOverflowToolTips のバックアップ(No.2)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- Swing/ComboBoxOverflowToolTips へ行く。
- 1 (2019-12-09 (月) 17:25:53)
- 2 (2021-06-10 (木) 20:46:37)
- category: swing folder: ComboBoxOverflowToolTips title: JComboBoxで文字列が溢れる場合はJToolTipを表示可能にする tags: [JComboBox, JToolTip, ListCellRenderer] author: aterai pubdate: 2019-12-09T17:24:04+09:00 description: JComboBoxのアイテム文字列がJComboBox本体またはドロップダウンリストのセルから溢れる場合のみJToolTipを表示可能に設定します。 image: https://drive.google.com/uc?id=1Gm4SDovuAp3RO8gdLagvzxvj5wComdW3
概要
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