---
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?id=1j4KzCS-He6w9JuyRopBvRfEgr3S-XgXxrA
---
* 概要 [#summary]
`JComboBox`のドロップダウンリストで使用される`JList`の選択背景色と選択文字色を変更します。

#download(https://drive.google.com/uc?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(...)`メソッドを使用してその選択背景色と選択文字色を変更
-- `MetalLookAndFeel`で編集不可の`JComboBox`の場合、`JComboBox`本体の選択背景色も変更される
-- `MetalLookAndFeel`で編集不可の`JComboBox`の場合`JComboBox`本体の選択背景色も変更される
- `DefaultListCellRenderer`
-- 参考: [[JComboBoxの文字色を変更する>Swing/ComboBoxForegroundColor]]
-- `DefaultListCellRenderer#getListCellRendererComponent(...)`メソッドをオーバーライドして選択背景色と選択文字色を変更
-- `MetalLookAndFeel`で編集不可の`JComboBox`の場合、`JComboBox`本体の選択背景色は変更されない
--- このサンプルの場合、ドロップダウンリストの選択背景色に設定したオレンジ色ではなく`UIManager.put("ComboBox.selectionBackground", Color.PINK)`で設定したピンク色になる
-- `MetalLookAndFeel`で編集不可の`JComboBox`の場合`JComboBox`本体の選択背景色は変更されない
--- このサンプルの場合ドロップダウンリストの選択背景色に設定したオレンジ色ではなく`UIManager.put("ComboBox.selectionBackground", Color.PINK)`で設定したピンク色になる
-- `JComboBox`本体のフォーカス時の`Border`(`WindowsLookAndFeel`の場合は`WindowsBorders.DashedBorder`)が非表示になる
--- 回避方法: セルの描画を`DefaultListCellRenderer`を継承するレンダラーではなく、`JComboBox#getRenderer()`で取得した`LookAndFeel`のデフォルトセルレンダラーに移譲するなどの方法がある
--- 回避方法: セルの描画を`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