JComboBoxのドロップダウンリストでアイテム選択状態表示をラウンド矩形に変更する
Total: 348
, Today: 2
, Yesterday: 1
Posted by aterai at
Last-modified:
概要
JComboBox
で使用するドロップダウンリストのアイテム選択状態表示をラウンド矩形に変更するListCellRenderer
を作成します。
Screenshot
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から取得するよう変更する
- このサンプルでは