Swing/ColorComboBox のバックアップの現在との差分(No.17)
TITLE:JComboBoxの色を変更
Posted by aterai at 2005-01-10
JComboBoxの色を変更
JComboBoxのEditor部分と、List部分の色を変更します。-
category: swing
folder: ColorComboBox
title: JComboBoxの色を変更
tags: [JComboBox, ListCellRenderer, JTextField]
author: aterai
pubdate: 2005-01-10T01:48:08+09:00
description: JComboBoxのEditor部分と、List部分の色を変更します。
image:
hreflang:
href: https://java-swing-tips.blogspot.com/2009/06/color-jcombobox.html lang: en
概要
JComboBox
のEditor
部分と、List
部分の色を変更します。
- &jnlp;
- &jar;
- &zip;
Screenshot
Advertisement
サンプルコード
#spanend
#spanadd
class AlternateRowColorComboBox<E> extends JComboBox<E> {
#spanend
private static final Color EVEN_BGC = new Color(0xE1_FF_E1);
private static final Color ODD_BGC = Color.WHITE;
private transient ItemListener itemColorListener;
#spandel
**サンプルコード [#b2f19a3d]
#spanend
#spandel
#code{{
#spanend
#spandel
combo01.setModel(makeModel());
#spanend
#spandel
combo01.setRenderer(new MyListCellRenderer(combo01.getRenderer()));
#spanend
#spandel
combo01.addItemListener(new ItemListener() {
#spanend
public void itemStateChanged(ItemEvent e) {
if(e.getStateChange()!=ItemEvent.SELECTED) return;
combo01.setBackground(getOEColor(combo01.getSelectedIndex()));
protected AlternateRowColorComboBox(ComboBoxModel<E> model) {
super(model);
}
#spandel
});
#spanend
#spandel
combo01.setSelectedIndex(0);
#spanend
#spandel
combo01.setBackground(evenBGColor);
#spanend
#spandel
final JTextField field = (JTextField) combo02.getEditor().getEditorComponent();
#spanend
#spandel
field.setOpaque(true);
#spanend
#spandel
field.setBackground(evenBGColor);
#spanend
#spandel
combo02.setEditable(true);
#spanend
#spandel
combo02.setModel(makeModel());
#spanend
#spandel
combo02.setRenderer(new MyListCellRenderer(combo02.getRenderer()));
#spanend
#spandel
combo02.addItemListener(new ItemListener() {
#spanend
public void itemStateChanged(ItemEvent e) {
if(e.getStateChange()!=ItemEvent.SELECTED) return;
field.setBackground(getOEColor(combo02.getSelectedIndex()));
@Override public void setEditable(boolean flag) {
super.setEditable(flag);
Component field = getEditor().getEditorComponent();
if (flag && field instanceof JComponent) {
((JComponent) field).setOpaque(true);
field.setBackground(getAlternateRowColor(getSelectedIndex()));
}
}
#spandel
});
#spanend
#spandel
combo02.setSelectedIndex(0);
#spanend
#spandel
View in GitHub: Java, Kotlin解説
JComboBoxを編集可にした状態で、以下のようにList部分、Editor部分に背景色を設定します。@Override public void updateUI() { removeItemListener(itemColorListener); super.updateUI(); ListCellRenderer<? super E> r = getRenderer(); setRenderer((list, value, index, isSelected, cellHasFocus) -> { Component c = r.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); if (index >= 0 && c instanceof JComponent) { ((JComponent) c).setOpaque(true); } if (!isSelected) { c.setBackground(getAlternateRowColor(index)); } return c; }); itemColorListener = e -> { if (e.getStateChange() != ItemEvent.SELECTED) { return; } JComboBox<?> cb = (JComboBox<?>) e.getItemSelectable(); Color rc = getAlternateRowColor(cb.getSelectedIndex()); if (cb.isEditable()) { cb.getEditor().getEditorComponent().setBackground(rc); } else { cb.setBackground(rc); } }; addItemListener(itemColorListener); EventQueue.invokeLater(() -> { Component c = getEditor().getEditorComponent(); c.setBackground(getAlternateRowColor(getSelectedIndex())); if (c instanceof JComponent) { ((JComponent) c).setOpaque(true); } }); }
- List部分
- ListCellRendererを使用することで背景色を変更しています。
protected static Color getAlternateRowColor(int index) { return index % 2 == 0 ? EVEN_BGC : ODD_BGC; }
} }}
- ListCellRendererを使用することで背景色を変更しています。
- Editor部分
- getEditor().getEditorComponent()でJTextFieldオブジェクトを取得して背景色を変更しています。
解説
上記のサンプルでは、JComboBox
を編集可にした状態で以下のようにList
部分、Editor
部分に行の奇数偶数で背景色を変更しています。
上記のサンプルでは、下のJComboBoxで行の奇数偶数による背景色の変更を行っています。
-
List
部分-
ListCellRenderer
を使用することで背景色を変更
-
-
Editor
部分-
getEditor().getEditorComponent()
でJTextField
オブジェクトを取得して背景色を変更
-
GWT L&Fなどで、うまくBox(Editor)部分の色を変更できない場合があるようです。
-
GTKLookAndFeel
などでBox
(Editor
)部分の色を変更できない場合がある
コメント
- JComboBox#setEditable(true)は必須のようです。編集不可にするにはEditor部分のJTextFieldに対してsetEditable(false) -- Y?
- ご指摘ありがとうございます。せっかくJComboBoxを上下に並べているのだから、編集可の場合と不可の場合のサンプルにすればよかったですね。編集不可の場合(JComboBox#setEditable(false))に色を着けるには、上記の方法と、以下のようにJComboBox#setBackground(Color)メソッドを使う方法があるようです。
編集不可の場合は、この部分の色もレンダラーが勝手にやってくれてたような気がするのですが、勘違いだったのかも。バージョンやL&Fで異なる?ようです。 -- aterai
- ご指摘ありがとうございます。せっかくJComboBoxを上下に並べているのだから、編集可の場合と不可の場合のサンプルにすればよかったですね。編集不可の場合(JComboBox#setEditable(false))に色を着けるには、上記の方法と、以下のようにJComboBox#setBackground(Color)メソッドを使う方法があるようです。
参考リンク
コメント
-
JComboBox#setEditable(true)
は必須のようです。編集不可にするにはEditor
部分のJTextField
に対してsetEditable(false)
-- Y- ご指摘ありがとうございます。せっかく
JComboBox
を上下に並べているので、編集可の場合と不可の場合のサンプルにすればよかったですね。編集不可の場合(JComboBox#setEditable(false)
)に色を着けるには、上記の方法と、以下のようにJComboBox#setBackground(Color)
メソッドを使う方法があるようです。編集不可の場合は、この部分の色もレンダラーが勝手にやってくれてたような気がするのですが、勘違いだったのかも。バージョンやLookAndFeel
で異なる?ようです。 -- aterai
- ご指摘ありがとうございます。せっかく
final JComboBox c = new JComboBox();
c.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
if(e.getStateChange()!=ItemEvent.SELECTED) return;
c.setBackground((c.getSelectedIndex()%2==0)?evenBGColor:oddBGColor);
@Override public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() != ItemEvent.SELECTED) {
return;
}
c.setBackground((c.getSelectedIndex() % 2 == 0) ? evenBGColor : oddBGColor);
}
});
- せっかくなので、上のJComboBoxは編集不可、下は編集可の場合で、色を着けるサンプルに変更しました。 -- aterai
- メモ:Windows/Motif L&F: Changing the JComboBox background does not change the popup of the JCombobox -- aterai
- サンプルソースのLookAndFeelを設定しないようにすると、編集不可コンボはボタン部分も背景色になってしまう・・ -- han?
- MetalLookAndFeel などは、コンボボックスの背景色を変更すると矢印ボタンの色まで変更してしまう仕様?みたいですね。回避するなら、以下のようにUIで使っているPropertyChangeListenerをオーバーライドしてしまうのはどうでしょう。 -- aterai
- せっかくなので、上の
JComboBox
は編集不可、下は編集可の場合で、色を着けるサンプルに変更しました。 -- aterai
- メモ: Windows/Motif L&F: Changing the JComboBox background does not change the popup of the JCombobox -- aterai
- サンプルソースの
LookAndFeel
を設定しないようにすると、編集不可コンボはボタン部分も背景色になってしまう・・ -- han-
MetalLookAndFeel
などは、コンボボックスの背景色を変更すると矢印ボタンの色まで変更してしまう仕様?みたいですね。回避するなら、以下のようにUI
で使っているPropertyChangeListener
をオーバーライドしてしまうのはどうでしょう。 -- aterai
-
combo01.setUI(new MetalComboBoxUI() {
@Override
public PropertyChangeListener createPropertyChangeListener() {
@Override public PropertyChangeListener createPropertyChangeListener() {
return new MetalPropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent e) {
@Override public void propertyChange(PropertyChangeEvent e) {
String propertyName = e.getPropertyName();
if(propertyName=="background") {
Color color = (Color)e.getNewValue();
if (propertyName == "background") {
Color color = (Color) e.getNewValue();
//arrowButton.setBackground(color);
listBox.setBackground(color);
}else{
} else {
super.propertyChange( e );
}
}
};
}
});
combo01.setModel(makeModel());
combo01.setRenderer(new MyListCellRenderer(combo01.getRenderer()));
combo01.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
if(e.getStateChange()!=ItemEvent.SELECTED) return;
@Override public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() != ItemEvent.SELECTED) {
return;
}
combo01.setBackground(getOEColor(combo01.getSelectedIndex()));
}
});
combo01.setSelectedIndex(0);
combo01.setBackground(evenBGColor);
- ありがとうございます。動作確認してませんがUIをさわればいろんなことができそうですね。でUIManagerでなんとかできないか気になったので試すと、UIManager.put("ComboBox.background", new ColorUIResource(Color.white));で全てのコンボボックスの背景色を設定できました(リストの色分けはできないですが) -- han?
- ありがとうございます。動作確認してませんが
UI
をさわればいろんなことができそうですね。でUIManager
でなんとかできないか気になったので試すと、UIManager.put("ComboBox.background", new ColorUIResource(Color.white));
で全てのコンボボックスの背景色を設定できました(リストの色分けはできないですが) -- han