开发者

Color of the dropdown control and border in an uneditable JComboBox

开发者 https://www.devze.com 2023-02-01 11:10 出处:网络
The background color of the selected item in an uneditable JComboBox is a sort of blue: I know that you can change it to a different color, such as white, for example with the following code:

The background color of the selected item in an uneditable JComboBox is a sort of blue:

Color of the dropdown control and border in an uneditable JComboBox

I know that you can change it to a different color, such as white, for example with the following code:

jComboBox1.setRenderer(new DefaultListCellRenderer() {
    @Override
    public void paint(Graphics g) {
        setBackground(Color.WHITE);
        setForeground(Color.BLACK);
        super.paint(g);
    }
});

That gives you something like this:

Color of the dropdown control and border in an uneditable JComboBox

However, if you double-click on that combo-box, some of it turns gray (the part with the triangle and the border):

Color of the dropdown control and border in an uneditable JComboBox

Is there a way to stop these开发者_Go百科 parts from turning gray when you double-click on it?

Note that, if you call super.paint() first, the whole thing turns dark (including the part behind "Select..."), so that doesn't help.


Not sure what exactly OP is trying to achieve, but here is my JComboBox coloring recipe:

static public void main(String[] args) {
    JFrame window = new JFrame("Coloring ComboBox");
    window.setSize(170, 150);
    window.setLocationRelativeTo(null);
    window.setLayout(null);
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    //---textArea is just for focus switching
    JTextArea textArea = new JTextArea();
    textArea.setBounds(5, 5, 140, 25);
    window.add(textArea);

    UIManager.put("ComboBox.selectionBackground", Color.magenta); //---focused background color
    //---see comboBox's UIDefaults for more tweaks

    JComboBox<String> coloredCombo = new JComboBox<String>(new String[]{"Dog", "Cat", "Bird"});
    coloredCombo.setEditable(false);
    coloredCombo.setUI(new BasicComboBoxUI() {
            @SuppressWarnings({"serial"})
            @Override
            protected ComboPopup createPopup() {
                return new BasicComboPopup(coloredCombo) {
                    {
                        //---style popup anyway you like
                        this.setBorder(BorderFactory.createLineBorder(Color.green, 2));//---popup's border color
                    }
                };
            }
            @Override
            protected JButton createArrowButton() {
                //---style arrow button anyway you like
                JButton result = new JButton();
                result.setBackground(Color.orange);//---button's color
                return result;
            }
        });

    coloredCombo.setBorder(BorderFactory.createLineBorder(Color.red, 2));//---border color
    coloredCombo.setBackground(Color.yellow); //---not focused background color

    coloredCombo.setRenderer(new ListCellRenderer<String>() {
        @Override
        public Component getListCellRendererComponent(JList<? extends String> list, String value, int index,
                boolean isSelected, boolean cellHasFocus) {
            JLabel result = new JLabel(value);
            result.setOpaque(true);
            result.setBackground(isSelected ? Color.cyan : Color.blue); //---item background color
            return result;
        }
    });
    coloredCombo.setBounds(5, 35, 140, 25);
    window.add(coloredCombo);

    window.setVisible(true);
}

Of course, this is just an axample, I recommend you to create a fancy custom class to reuse.

Color of the dropdown control and border in an uneditable JComboBox


A couple things:

  1. The appearance of the combobox (the display area, the arrow, the drop down) are LAF dependent. Your screen shots suggest WinXP. If you must support any other LAFs, be sure to test that as well, because what works for one LAF may not work for another. I have found this to be particularly true for JComboBoxes.

  2. Like Twister suggests, changing the color by overriding the paint() method likely isn't the best way to do this. Just set the background/foreground color of the combobox itself. If you want to change the color of the dropdown itself (I'm not clear if you want to do this or not), then add a custom renderer that overrides getListCellRendererComponent to set the background/foreground.

    public static class CustomRenderer extends DefaultListCellRenderer {
    
    @Override
    public Component getListCellRendererComponent(JList list, Object value,
            int index, boolean isSelected, boolean cellHasFocus) {
        super.getListCellRendererComponent(list, value, index, isSelected,
                cellHasFocus);
        setBackground(Color.WHITE);
        setForeground(Color.BLACK);     
        return this;
    }       
    

    }

  3. The appearance of the grey triangle and border is because the combo box now has focus. You can just make it not focusable, and the coloring will go away. This may not be the behavior you want, however.

    JComboBox combo = new JComboBox(new Object[]{"Dog", "Cat", "Bird"});
    combo.setBackground(Color.WHITE);
    combo.setForeground(Color.BLACK);
    combo.setFocusable(false);
    


First, you should not set the foreground and background in the paint method. You should override the getListCellRendererComponent of your renderer in order to customize it. The default renderer change its aspect if you it has the focus or if it is selected. If you do not want those features reimplements the method.

Then if you add a line border to your renderer (setBorder(BorderFactory.createLineBorder(Color.black)) you will see that what is drawn is not part of your renderer but the combobox itself. So you might have to customize the UI


The swing code that calls getListCellRendererComponent, then calls setForeground and setBackground on the returned component (depending on the whether the component is selected and/or focused). I assume this is for some legacy behavior. Unfortunately, it defeats the purpose of my setting it in the renderer.

I've had some good results with this approach:

The code below circumvents changing the foreground and background by overriding the fg/bg setters to do nothing, then I just call the super implementations to set the colors I want.

public static class CustomRenderer extends DefaultListCellRenderer {
    public Component getListCellRendererComponent(JList list, Object value,
        int index, boolean isSelected, boolean cellHasFocus) {
        super.getListCellRendererComponent(list, value, index, isSelected,
            cellHasFocus);
        super.setBackground(Color.WHITE);
        super.setForeground(Color.BLACK);     
        return this;
    }
    public void setForeground(Color c) {}
    public void setBackground(Color c) {}
}

Addendum: The grey border is probably just that, a border. Try the same approach, but also override setBorder.

0

精彩评论

暂无评论...
验证码 换一张
取 消