Java 在JComboBox中更改选择的颜色(选择后)

Java 在JComboBox中更改选择的颜色(选择后),java,swing,jcombobox,listcellrenderer,Java,Swing,Jcombobox,Listcellrenderer,我正在使用Swing编写GUI。我有一个自定义编写的JComboBox,使用ListCellRenderer和basicmboboxeditor 在我的getListCellRenderComponent()方法中,我根据项目是否被“选中”(鼠标悬停在上方)来更改列表的颜色,这很好,但我不希望一旦做出选择,选择就会更改背景色,而当前就是这样 第一张图片显示了界面在进行选择之前的外观,第二张图片显示了界面在进行选择之后的外观 问题: 如何将“选择”的背景更改为“stockColor” MCVE

我正在使用Swing编写GUI。我有一个自定义编写的
JComboBox
,使用
ListCellRenderer
basicmboboxeditor

在我的
getListCellRenderComponent()
方法中,我根据项目是否被“选中”(鼠标悬停在上方)来更改列表的颜色,这很好,但我不希望一旦做出选择,选择就会更改背景色,而当前就是这样

第一张图片显示了界面在进行选择之前的外观,第二张图片显示了界面在进行选择之后的外观

问题: 如何将“选择”的背景更改为“stockColor”

MCVE
导入java.awt.BorderLayout;
导入java.awt.Color;
导入java.awt.Component;
导入java.awt.Dimension;
导入java.awt.FlowLayout;
导入java.util.Vector;
导入javax.swing.DefaultComboxModel;
导入javax.swing.JButton;
导入javax.swing.JComboBox;
导入javax.swing.JFrame;
导入javax.swing.JLabel;
导入javax.swing.JList;
导入javax.swing.JPanel;
导入javax.swing.ListCellRenderer;
导入javax.swing.plaf.basic.BasicComboxeditor;
公共类TFComboBox扩展了JComboBox{
公共静态void main(字符串[]args){
createAndShowGUI();
}
公共静态void createAndShowGUI(){
JFrame=新JFrame(“MCVE”);
JPanel窗格=新的JPanel(新的BorderLayout());
TFComboBox cb=新的TFComboBox();
布尔[]tf={true,false};
cb.补充项目(tf);
JButton b=新JButton(“单击我!”);
添加(cb,BorderLayout.CENTER);
窗格。添加(b,边框布局。线条结束);
框架。添加(窗格);
frame.setLocationRelativeTo(空);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
私有模型;
私有向量项;
专用JComboBox组合框;
公共TFComboBox(){
comboBoxItems=新向量();
comboBoxItems.add(Boolean.TRUE);
comboBoxItems.add(Boolean.FALSE);
comboBox=新的JComboBox(comboBoxItems);
model=新的DefaultComboxModel();
setModel(model);
setRenderer(新的TrueFalseComboRenderer());
setEditor(新的TrueFalseComboEditor());
}
公共无效附加项(布尔[]项){
用于(布尔型anItem:items){
模型.加法(anItem);
}
}
}
类TrueFalseComboRenderer扩展了JPanel实现ListCellRenderer{
私有JLabel labelItem=新JLabel();
private Color stockColor=labelItem.getBackground();
公共TrueFalseComboRenderer(){
setLayout(新的BorderLayout());
labelItem.set不透明(真);
labelItem.设置水平对齐(JLabel.中心);
添加(labelItem);
立根背景(颜色:浅灰色);
}
@凌驾
公共组件GetListCellRenderComponent(JList列表、对象值、,
整型索引,布尔型isSelected,布尔型cellHasFocus){
布尔值=(布尔)值;
labelItem.setText(Boolean.toString(tempValue));
如果(当选){
labelItem.退化背景(stockColor.深色());
前景色(颜色:白色);
}否则{
labelItem.退化背景(stockColor);
labelItem。前景色(颜色。黑色);
}
归还这个;
}   
}
类TrueFalseComboxeEditor扩展BasicComboxeditor{
私有JLabel labelItem=新JLabel();
private JPanel panel=new JPanel();
私有对象selectedItem;
公共TrueComboEditor(){
labelItem.刚毛不透明(假);
labelItem.设置水平对齐(JLabel.中心);
前景色(颜色:白色);
面板设置布局(新的FlowLayout(FlowLayout.LEFT,5,2));
面板.立根背景(颜色.蓝色);
面板。添加(labelItem);
}
公共组件getEditorComponent(){
返回此.panel;
}
公共对象getItem(){
返回此项。选择编辑项;
}
公共无效集合项(对象项){
如果(项==null){
返回;
}
this.selectedItem=项目;
labelItem.setText(item.toString());
}
}
编辑 我添加了一个MCVE,您可以看到,JComboBox关注的“问题”与我的问题有关。我在组合框旁边放置了一个按钮,以帮助从组合框中移除焦点

只需执行一个
setFocusable(false)
就可以修复它,但也会带走程序其余部分的一些功能,因此这是不需要的。

  • 为了获得更好的帮助,请尽快在局部变量中发布一个
    SSCCE/MCVE
    ,简短、可运行、可编译,带有
    JComboBox
    /
    xxxcomboxmodel
    的硬编码值
  • JList在API中默认实现了布尔数组(不知道隐藏了什么)
    String trueFalseItem=Boolean.toString(tempValue);
    并存储值
    JComboBox模型
  • 这只是测试
    isSelected
    和更改
    JList.setSelectionXxx
    内部
    DefaultListCellRenderer
例如(SSCCE/MCVE格式的代码)

导入java.awt.Color;
导入java.awt.Component;
导入java.awt.event.ActionEvent;
导入java.util.Vector;
导入javax.swing.AbstractAction;
导入javax.swing.Action;
导入javax.swing.DefaultListCellRenderer;
导入javax.swing.JComboBox;
导入javax.swing.JFrame;
导入javax.swing.JLabel;
导入javax.swing.JList;
导入javax.swing.SwingUtilities;
公共类ComboxBoolean模型{
private javax.swing.Timer=null;
私有向量项;
私人JComboBox;
公共ComboxBooleanModel(){
comboBoxItems=新向量();
comboBoxItems.add(Boolean.TRUE);
comboBoxItems.add(布尔值)
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());
    }
}
import java.awt.Color;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.util.Vector;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.SwingUtilities;

public class ComboBoxBooleanModel {

    private javax.swing.Timer timer = null;
    private Vector<Boolean> comboBoxItems;
    private JComboBox box;

    public ComboBoxBooleanModel() {
        comboBoxItems = new Vector<Boolean>();
        comboBoxItems.add(Boolean.TRUE);
        comboBoxItems.add(Boolean.FALSE);
        box = new JComboBox(comboBoxItems);
        box.setRenderer(new DefaultListCellRenderer() {
            @Override
            public Component getListCellRendererComponent(JList list, Object value,
                    int index, boolean isSelected, boolean cellHasFocus) {
                Component c = super.getListCellRendererComponent(
                        list, value, index, isSelected, cellHasFocus);
                if (c instanceof JLabel) {
                    JLabel l = (JLabel) c;
                    if (Boolean.TRUE.equals(value)) {
                        l.setBackground(Color.RED);
                        if (isSelected) {
                            list.setSelectionForeground(Color.RED);
                            list.setSelectionBackground(Color.BLUE);
                        }
                    } else if (Boolean.FALSE.equals(value)) {
                        l.setBackground(Color.BLUE);
                        if (isSelected) {
                            list.setSelectionForeground(Color.BLUE);
                            list.setSelectionBackground(Color.RED);
                        }
                    }
                    return l;
                }
                return c;
            }
        });
        JFrame frame = new JFrame("");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(box);
        frame.setLocationRelativeTo(null);
        frame.pack();
        frame.setVisible(true);
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                box.setSelectedIndex(1);
            }
        });
        start();
    }

    private void start() {
        timer = new javax.swing.Timer(2250, updateCol());
        timer.start();
    }

    public Action updateCol() {
        return new AbstractAction("text load action") {
            private static final long serialVersionUID = 1L;

            @Override
            public void actionPerformed(ActionEvent e) {
                if (box.getSelectedItem() == (Boolean) false) {
                    box.setSelectedItem((Boolean) true);
                } else {
                    box.setSelectedItem((Boolean) false);
                }
            }
        };
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                ComboBoxBooleanModel comboBoxModel = new ComboBoxBooleanModel();
            }
        });
    }
}
public static void main(String[] args){

    JFrame frame = new JFrame("Combos BG Color test");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setLocationRelativeTo(null);
    frame.getContentPane().setPreferredSize(new Dimension(400, 40));

    JPanel mainPanel = new JPanel();
    mainPanel.setLayout(new GridLayout(1,2));
    frame.add(mainPanel);

    JComboBox<String> aCombo = new JComboBox<>(new String[]{"A","B","C"});
    mainPanel.add(aCombo);

    JComboBox<String> bCombo = new JComboBox<>(new String[]{"1","2","3"});
    Color bgColor = bCombo.getBackground();
    bCombo.setRenderer(new DefaultListCellRenderer() {
        @Override
        public void paint(Graphics g) {
            setBackground(bgColor);
            super.paint(g);
        }
    });

    mainPanel.add(bCombo);
    frame.pack();
    frame.setVisible(true);
}