---
category: swing
folder: ComboBoxSelectionBackground
title: JComboBoxのドロップダウンリストでの選択背景色を変更する
tags: [JComboBox, JList, UIManager]
author: aterai
pubdate: 2017-09-18T18:34:08+09:00
description: JComboBoxのドロップダウンリストで使用されるJListの選択背景色と選択文字色を変更します。
image: https://drive.google.com/uc?export=view&id=1j4KzCS-He6w9JuyRopBvRfEgr3S-XgXxrA
---
* 概要 [#summary]
`JComboBox`のドロップダウンリストで使用される`JList`の選択背景色と選択文字色を変更します。

#download(https://drive.google.com/uc?export=view&id=1j4KzCS-He6w9JuyRopBvRfEgr3S-XgXxrA)

* サンプルコード [#sourcecode]
#code(link){{
UIManager.put("ComboBox.selectionBackground", Color.PINK);
UIManager.put("ComboBox.selectionForeground", Color.CYAN);

String[] model = {"111", "2222", "33333"};

JComboBox<String> combo0 = new JComboBox<>(model);

JComboBox<String> combo1 = new JComboBox<String>(model) {
  @Override public void updateUI() {
    super.updateUI();
    Object o = getAccessibleContext().getAccessibleChild(0);
    if (o instanceof ComboPopup) {
      JList list = ((ComboPopup) o).getList();
      list.setSelectionForeground(Color.WHITE);
      list.setSelectionBackground(Color.ORANGE);
    }
  }
};

JComboBox<String> combo2 = new JComboBox<String>(model) {
  @Override public void updateUI() {
    super.updateUI();
    setRenderer(new DefaultListCellRenderer() {
      @Override public Component getListCellRendererComponent(
          JList list, Object value, int index,
          boolean isSelected, boolean hasFocus) {
        JLabel l = (JLabel) super.getListCellRendererComponent(
            list, value, index, isSelected, hasFocus);
        if (isSelected) {
          l.setForeground(Color.WHITE);
          l.setBackground(Color.ORANGE);
        } else {
          l.setForeground(Color.BLACK);
          l.setBackground(Color.WHITE);
        }
        return l;
      }
    });
  }
};
}}

* 解説 [#explanation]
- `UIManager.put(ComboBox.selection*, ...)`
-- `UIManager.put("ComboBox.selectionBackground", bgc);`、`UIManager.put("ComboBox.selectionForeground", fgc);`を使用して`JList`の選択背景色と選択文字色を変更
-- ドロップダウンリストで使用される`JList`のみが対象
-- `LookAndFeel`に依存し、例えば`NimbusLookAndFeel`ではどちらの指定も無効
- `ComboPopup.getList().setSelection*(...)`
-- `JComboBox#getAccessibleContext()#getAccessibleChild(0)`で`ComboPopup`を取得
-- `ComboPopup#getList()`メソッドでドロップダウンリストで使用される`JList`を取得
-- `JList#setSelectionForeground(...)`、`JList#setSelectionBackground(...)`メソッドを使用してその選択背景色と選択文字色を変更
- `DefaultListCellRenderer`
-- 参考: [[JComboBoxの文字色を変更する>Swing/ComboBoxForegroundColor]]
-- `DefaultListCellRenderer#getListCellRendererComponent(...)`メソッドをオーバーライドして選択背景色と選択文字色を変更
-- `JComboBox`本体のフォーカス時の`Border`(`WindowsLookAndFeel`の場合は`WindowsBorders.DashedBorder`)が非表示になる
--- 回避方法: セルの描画を`DefaultListCellRenderer`を継承するレンダラーではなく、`JComboBox#getRenderer()`で取得した`LookAndFeel`デフォルトのレンダラーに移譲するなどの方法がある
#code{{
JComboBox<String> combo3 = new JComboBox<String>(model) {
  @Override public void updateUI() {
    setRenderer(null);
    super.updateUI();
    ListCellRenderer<? super String> defaultRenderer = getRenderer();
    setRenderer(new ListCellRenderer<String>() {
      @Override public Component getListCellRendererComponent(
          JList<? extends String> list, String value, int index,
          boolean isSelected, boolean hasFocus) {
        JLabel l = (JLabel) defaultRenderer.getListCellRendererComponent(
            list, value, index, isSelected, hasFocus);
        if (isSelected) {
          l.setForeground(Color.WHITE);
          l.setBackground(Color.ORANGE);
        } else {
          l.setForeground(Color.BLACK);
          l.setBackground(Color.WHITE);
        }
        return l;
      }
    });
  }
};
}}

* 参考リンク [#reference]
- [[JComboBoxの色を変更>Swing/ColorComboBox]]
- [[JComboBoxの文字色を変更する>Swing/ComboBoxForegroundColor]]
- [https://docs.oracle.com/javase/jp/8/docs/api/javax/swing/plaf/basic/ComboPopup.html#getList-- ComboPopup#getList() (Java Platform SE 8)]

* コメント [#comment]
#comment
#comment