最近一时兴起,想玩一下swing;用它做一个小工具。由于原版界面不怎么好看,于是准备修改一下界面颜色;在修改JComboBox的时候,查了很多资料,仍然没有解决我的问题。最终通过不断的尝试,得以解决。留下笔记,给遇到类似问题的一个参考。
在查找资料的解决问题的过程当中,看到一篇博客,虽然不是我想要的结果。但将它贴出的代码加以修改,最终达到自己的目的。该博客地址链接:https://stackoverflow.com/questions/38200477/change-color-of-selection-after-selection-in-a-jcombobox?newreg=d1324fe4f4ac4c379e6e15ec5465b11e
引用此博客代码:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.util.Vector;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.ListCellRenderer;
import javax.swing.plaf.basic.BasicComboBoxEditor;
public class TFComboBox extends JComboBox{
public static void main(String[] args){
createAndShowGUI();
}
public static void createAndShowGUI(){
JFrame frame = new JFrame("MCVE");
JPanel pane = new JPanel(new BorderLayout());
TFComboBox cb = new TFComboBox();
boolean[] tf = {true, false};
cb.addItems(tf);
JButton b = new JButton("Click me!");
pane.add(cb, BorderLayout.CENTER);
pane.add(b, BorderLayout.LINE_END);
frame.add(pane);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
private DefaultComboBoxModel model;
private Vector<Boolean> comboBoxItems;
private JComboBox comboBox;
public TFComboBox(){
comboBoxItems = new Vector<Boolean>();
comboBoxItems.add(Boolean.TRUE);
comboBoxItems.add(Boolean.FALSE);
comboBox = new JComboBox(comboBoxItems);
model = new DefaultComboBoxModel();
setModel(model);
setRenderer(new TrueFalseComboRenderer());
setEditor(new TrueFalseComboEditor());
}
public void addItems(boolean[] items){
for(boolean anItem : items){
model.addElement(anItem);
}
}
}
class TrueFalseComboRenderer extends JPanel implements ListCellRenderer {
private JLabel labelItem = new JLabel();
private Color stockColor = labelItem.getBackground();
public TrueFalseComboRenderer(){
setLayout(new BorderLayout());
labelItem.setOpaque(true);
labelItem.setHorizontalAlignment(JLabel.CENTER);
add(labelItem);
setBackground(Color.LIGHT_GRAY);
}
@Override
public Component getListCellRendererComponent(JList list, Object value,
int index, boolean isSelected, boolean cellHasFocus) {
boolean tempValue = (boolean) value;
labelItem.setText(Boolean.toString(tempValue));
if(isSelected){
labelItem.setBackground(stockColor.darker());
labelItem.setForeground(Color.WHITE);
} else {
labelItem.setBackground(stockColor);
labelItem.setForeground(Color.BLACK);
}
return this;
}
}
class TrueFalseComboEditor extends BasicComboBoxEditor {
private JLabel labelItem = new JLabel();
private JPanel panel = new JPanel();
private Object selectedItem;
public TrueFalseComboEditor() {
labelItem.setOpaque(false);
labelItem.setHorizontalAlignment(JLabel.CENTER);
labelItem.setForeground(Color.WHITE);
panel.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 2));
panel.setBackground(Color.BLUE);
panel.add(labelItem);
}
public Component getEditorComponent(){
return this.panel;
}
public Object getItem(){
return this.selectedItem;
}
public void setItem(Object item){
if(item == null){
return;
}
this.selectedItem = item;
labelItem.setText(item.toString());
}
}
运行效果:
本人想要实现的效果:在JComboBox中选择之后,点击按钮;JComboBox的背景色和字体颜色都维持该颜色,而不发生改变。目的是为了和小工具主题的颜色匹配
修改以上源码如下:
package com.quan.test.JComboBox.test3;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.FlowLayout;
import java.util.Vector;
import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.ListCellRenderer;
import javax.swing.plaf.basic.BasicComboBoxEditor;
import com.quan.test.JComboBox.test3.TrueFalseComboRenderer;
public class TFComboBox extends JComboBox{
public static void main(String[] args){
createAndShowGUI();
}
public static void createAndShowGUI(){
JFrame frame = new JFrame("MCVE");
JPanel pane = new JPanel(new BorderLayout());
TFComboBox cb = new TFComboBox();
boolean[] tf = {true, false};
cb.addItems(tf);
JButton b = new JButton("Click me!");
pane.add(cb, BorderLayout.CENTER);
pane.add(b, BorderLayout.LINE_END);
pane.setBackground(new Color(166, 166, 166));
frame.add(pane);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
private DefaultComboBoxModel model;
private Vector<Boolean> comboBoxItems;
private JComboBox comboBox;
public TFComboBox(){
comboBoxItems = new Vector<Boolean>();
comboBoxItems.add(Boolean.TRUE);
comboBoxItems.add(Boolean.FALSE);
comboBox = new JComboBox(comboBoxItems);
model = new DefaultComboBoxModel();
setModel(model);
setRenderer(new TrueFalseComboRenderer());
setEditor(new TrueFalseComboEditor());
setOpaque(false);
setBackground(new Color(166, 166, 166));
setForeground(Color.WHITE);
}
public void addItems(boolean[] items){
for(boolean anItem : items){
model.addElement(anItem);
}
}
}
class TrueFalseComboRenderer implements ListCellRenderer {
private DefaultListCellRenderer defaultCellRenderer = new DefaultListCellRenderer();
public TrueFalseComboRenderer(){
super();
}
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
JLabel labelItem = (JLabel) defaultCellRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
boolean tempValue = (boolean) value;
labelItem.setText(Boolean.toString(tempValue));
if(isSelected){
labelItem.setBackground(Color.GRAY);
labelItem.setForeground(Color.WHITE);
} else {
labelItem.setBackground(new Color(238, 238, 238));
labelItem.setForeground(Color.black);
}
list.setSelectionForeground(Color.WHITE);
list.setSelectionBackground(new Color(166, 166, 166));;
return labelItem;
}
}
class TrueFalseComboEditor extends BasicComboBoxEditor {
private JLabel labelItem = new JLabel();
private JPanel panel = new JPanel();
private Object selectedItem;
public TrueFalseComboEditor() {
labelItem.setOpaque(false);
labelItem.setHorizontalAlignment(JLabel.CENTER);
labelItem.setForeground(Color.WHITE);
panel.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 2));
panel.setBackground(Color.BLUE);
panel.add(labelItem);
}
public Component getEditorComponent(){
return this.panel;
}
public Object getItem(){
return this.selectedItem;
}
public void setItem(Object item){
if(item == null){
return;
}
this.selectedItem = item;
labelItem.setText(item.toString());
}
}
修改之后的效果:
这样大概已经实现了本人想要的效果。
主要修改的源码:
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
JLabel labelItem = (JLabel) defaultCellRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
boolean tempValue = (boolean) value;
labelItem.setText(Boolean.toString(tempValue));
if(isSelected){
// 配置下拉框内鼠标选中时的背景色和前景色
labelItem.setBackground(Color.GRAY);
labelItem.setForeground(Color.WHITE);
} else {
labelItem.setBackground(new Color(238, 238, 238));
labelItem.setForeground(Color.black);
}
// 在这里加上选择后的配置
list.setSelectionForeground(Color.WHITE);
list.setSelectionBackground(new Color(166, 166, 166));;
return labelItem;
}