Swing/RoundedCornerListCellRenderer のバックアップ(No.2)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- Swing/RoundedCornerListCellRenderer へ行く。
- 1 (2024-02-19 (月) 03:06:36)
- 2 (2024-07-05 (金) 10:49:07)
- category: swing folder: RoundedCornerListCellRenderer title: JComboBoxのドロップダウンリストでアイテム選択状態表示をラウンド矩形に変更する tags: [JComboBox, JList, ListCellRenderer] author: aterai pubdate: 2024-02-19T03:05:38+09:00 description: JComboBoxで使用するドロップダウンリストのアイテム選択状態表示をラウンド矩形に変更するListCellRendererを作成します。 image: https://drive.google.com/uc?id=1rMdApPD-7KgcOs2jLFTbRXqcI_SUe6IR
概要
JComboBox
で使用するドロップダウンリストのアイテム選択状態表示をラウンド矩形に変更するListCellRenderer
を作成します。
Screenshot
![Swing/RoundedCornerListCellRenderer screenshot](https://ateraimemo.com/swing/roundedcornerlistcellrenderer/screenshot.png)
Advertisement
サンプルコード
class RoundedCornerListCellRenderer<E> implements ListCellRenderer<E> {
private static final Icon GAP = new GapIcon();
private final DefaultListCellRenderer renderer = new DefaultListCellRenderer() {
@Override protected void paintComponent(Graphics g) {
if (getIcon() != null) {
Graphics2D g2 = (Graphics2D) g.create();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setPaint(getBackground());
Rectangle r = SwingUtilities.calculateInnerArea(this, null);
g2.fill(new RoundRectangle2D.Float(r.x, r.y, r.width, r.height, 10f, 10f));
super.paintComponent(g2);
g2.dispose();
} else {
super.paintComponent(g);
}
}
};
@Override public Component getListCellRendererComponent(JList<? extends E> list, E value, int index, boolean isSelected, boolean cellHasFocus) {
Component c = renderer.getListCellRendererComponent(
list, value, index, isSelected, cellHasFocus);
if (c instanceof JLabel) {
JLabel label = (JLabel) c;
label.setOpaque(false);
label.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
label.setIconTextGap(0);
label.setIcon(index >= 0 ? GAP : null);
// Nimbus DerivedColor bug?
Color fgc = isSelected
? new Color(list.getSelectionForeground().getRGB())
: list.getForeground();
label.setForeground(fgc);
}
return c;
}
}
class GapIcon implements Icon {
@Override public void paintIcon(Component c, Graphics g, int x, int y) {
/* Empty paint */
}
@Override public int getIconWidth() {
return 2;
}
@Override public int getIconHeight() {
return 18;
}
}
View in GitHub: Java, Kotlin解説
DefaultListCellRenderer#paintComponent(...)
をオーバーライドしてアイテム選択時(このサンプルでは左余白として使用しているIcon
が設定されている場合)選択状態表示を矩形ではなくラウンド矩形で描画するよう変更JLabel#setOpaque(false)
で背景を描画しないよう設定し、ラウンド矩形の上にアイテムテキストのみ描画する必要がある- ラウンド矩形とアイテムのテキストの間隔は空のアイコンと
JLabel#setIconTextGap(...)
で調整
NimbusLookAndFeel
でSynthComboBoxRenderer
ではなくDefaultListCellRenderer
を使用するとJList#getSelectionBackground()
がDerivedColor
を返すので選択文字色が黒になってしまう?- このサンプルでは
new Color(JList#getSelectionForeground()#getRGB())
とDerivedColor
をColor
に変換してレンダラーに渡すことで回避している - NimbusLookAndFeelでセル選択色をJListから取得するよう変更する
- このサンプルでは