NimbusLookAndFeelでJComboBoxのセル選択色などを変更する
Total: 465
, Today: 2
, Yesterday: 0
Posted by aterai at
Last-modified:
概要
NimbusLookAndFeel
でJComboBox
の背景色、セル選択色や選択文字色などを変更します。
Screenshot
Advertisement
サンプルコード
UIManager.put("ComboBox.forceOpaque", Boolean.FALSE);
Insets ins = UIManager.getInsets("ComboBox.padding");
ins.right = 0;
UIManager.put("ComboBox.padding", ins);
// ...
JComboBox<String> comboBox = new JComboBox<>(MODEL);
comboBox.setForeground(Color.WHITE);
comboBox.setBackground(BACKGROUND);
UIDefaults d1 = new UIDefaults();
d1.put("ComboBox:\"ComboBox.listRenderer\".background", BACKGROUND);
d1.put("ComboBox:\"ComboBox.listRenderer\".textForeground", Color.WHITE);
d1.put("ComboBox:\"ComboBox.listRenderer\"[Selected].background", Color.LIGHT_GRAY);
d1.put("ComboBox:\"ComboBox.listRenderer\"[Selected].textForeground", Color.BLACK);
// d1.put("ComboBox:\"ComboBox.listRenderer\".opaque", Boolean.TRUE);
ListCellRenderer<? super String> renderer = comboBox.getRenderer();
if (renderer instanceof JComponent) {
putClientProperty((JComponent) renderer, d1);
}
// ...
private static final class ComboRenderer extends DefaultListCellRenderer {
@Override public Component getListCellRendererComponent(
JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
list.setBackground(BACKGROUND);
list.setForeground(Color.WHITE);
list.setSelectionBackground(Color.LIGHT_GRAY);
list.setSelectionForeground(Color.BLACK);
return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
}
}
// ...
private static JComboBox<String> makeComboBox2() {
return new JComboBox<String>(MODEL) {
@Override public void updateUI() {
setRenderer(null);
super.updateUI();
ListCellRenderer<? super String> r = getRenderer();
setRenderer((list, value, index, isSelected, cellHasFocus) -> {
Component c = r.getListCellRendererComponent(
list, value, index, isSelected, cellHasFocus);
((JComponent) c).setOpaque(true);
return c;
});
ComboPopup popup = (ComboPopup) getAccessibleContext().getAccessibleChild(0);
JList<?> list = popup.getList();
list.setBackground(BACKGROUND);
list.setForeground(Color.WHITE);
list.setSelectionBackground(Color.LIGHT_GRAY);
list.setSelectionForeground(Color.BLACK);
setBackground(BACKGROUND);
}
};
}
View in GitHub: Java, Kotlin解説
UIDefaults
- 以下の色を
JComboBox
のセルレンダラーに設定UIDefaults#put("ComboBox:\"ComboBox.listRenderer\".background", BACKGROUND)
UIDefaults#put("ComboBox:\"ComboBox.listRenderer\".textForeground", Color.WHITE)
UIDefaults#put("ComboBox:\"ComboBox.listRenderer\"[Selected].background", Color.LIGHT_GRAY)
UIDefaults#put("ComboBox:\"ComboBox.listRenderer\"[Selected].textForeground", Color.WHITE)
UIManager.put("ComboBox.forceOpaque", Boolean.FALSE)
を設定してもJComboBox
自体の描画はJComboBox.setBackground(...)
で設定した色に変更されない?- カーソルキーで選択状態を変更すれば先頭セル以外の選択背景色は変化する?
- マウスオーバーによる状態変化は下方向にのみ有効で上方向には反応しない?
- ドロップダウンリストの下辺に
JList
の背景色が描画されるUIManager.put("ComboBox.popupInsets", ...)
はドロップダウンリストの内余白ではなく外余白を変更するので
- 以下の色を
DefaultListCellRenderer
UIManager.put("ComboBox.forceOpaque", Boolean.FALSE)
を設定してJComboBox
自体の背景色をJComboBox.setBackground(...)
で設定した色に変更DefaultListCellRenderer#getListCellRendererComponent(...)
をオーバーライドしてJList
の背景色、文字色、選択背景色、選択文字色を変更UIManager.put("ComboBox.padding", new Insets(3, 3, 3, 0))
を設定して右余白を除去しないと矢印ボタンとの間に設定した背景色で描画されない領域が生成されてしまう?
ComboPopup
- 上記の
DefaultListCellRenderer
同様、UIManager.put("ComboBox.forceOpaque", Boolean.FALSE)
を設定、セルレンダラーは反対にsetOpaque(true)
で不透明化してJComboBox
自体の背景色をJComboBox.setBackground(...)
で設定した色に変更 (ComboPopup) JComboBox#getAccessibleContext().getAccessibleChild(0)
でComboPopup
を取得し、さらにComboPopup#getList()
でドロップダウンリストで使用するJList
を取得してその背景色、文字色、選択背景色、選択文字色を変更- 上記の
DefaultListCellRenderer
同様、UIManager.put("ComboBox.padding", new Insets(3, 3, 3, 0))
を設定して右余白を除去しないと矢印ボタンとの間に設定した背景色で描画されない領域が生成されてしまう?
- 上記の
参考リンク
- Nimbus Defaults (The Java™ Tutorials > Creating a GUI With Swing > Modifying the Look and Feel)
- JComboBoxの内余白
- java - JComboBox background is not painted untill hover over it - Stack Overflow
- NimbusLookAndFeelでセル選択色をJListから取得するよう変更する