0

Hi !

I'd like to know how i can change the default focused background and foreground for a JComboBox. Since i made it extends a DefaultListCellRenderer, which is modifying both foreground and background for each of its items, i don't like that it doesn't respect them when it gains focus. I've tried UIMnager.put("ComboBox.background", new ColorUIResource(my_color)); and some other keys (every single one i could find, actually) as first thing SwingUtilities does, without any success. I didn't make any change in UIManager inside this program, neither before nor after, so the look and feel is the default one (Metal), as it's provide at first by Java 13. Is there a way to do so ?

Edit: here is a sample to see what i mean :

package tests;

import java.awt.Color;
import java.awt.Component;
import java.awt.GridLayout;

import javax.swing.DefaultListCellRenderer;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

final class ComboBoxTest implements Runnable {
    public static void main(String[]arguments_) {
        SwingUtilities.invokeLater(new ComboBoxTest());
    }
    @Override
    public void run() {
        JFrame frame_ = new JFrame("JComboBox Test");
        JPanel panel_ = new JPanel(new GridLayout(3, 1));
        JComboBox<String>
        useless_box = new JComboBox<>()
        , tested_box = new JComboBox<>(new String[] {
            "<html>&#x26C8</html>", "<html>&#x2620</html>"
        });
        tested_box.setBackground(Color.ORANGE);
        tested_box.setForeground(Color.RED.darker().darker());
        tested_box.setFont(tested_box.getFont().deriveFont(48.f));
        tested_box.setRenderer(new ComboRenderer());
        panel_.add(new JPanel());
        panel_.add(useless_box);
        panel_.add(tested_box);
        frame_.add(panel_);
        frame_.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame_.setLocationRelativeTo(null);
        frame_.pack();
        frame_.setVisible(true);
    }
    private class ComboRenderer extends DefaultListCellRenderer {
        /**
         * 
         */
        private static final long serialVersionUID = -1329981614961331328L;
        @Override
        public Component getListCellRendererComponent (
            JList<? extends Object>list_, Object value_        
            , int index_, boolean is_selected, boolean cell_has_focus
        ) {
            super.getListCellRendererComponent (
                list_, value_, index_, is_selected, cell_has_focus
            );
            setHorizontalAlignment(DefaultListCellRenderer.CENTER);
            switch(index_) {
            case -1:
                setBackground(Color.ORANGE);
                break;
            default:
                if(is_selected == true) {
                    setBackground(Color.ORANGE.darker());
                } else {
                    setBackground(Color.ORANGE);
                }
                break;
            }
            setForeground(Color.RED.darker().darker());
            return this;
        }
    }
}

The first box (at the middle) and the JPanel (at the top) are here to see what happens to the second one when it gains the focus or loses it, transfering the focus or not completely (by clicking on the JPanel instead of the JComboBox itself or an other selectable JComponent).

Oliv
  • 13
  • 3
  • Post your [mre] demonstrating the problem. – camickr Nov 26 '20 at 00:46
  • I prepare that... – Oliv Nov 26 '20 at 02:48
  • Ok, it's done. So when the `JFrame` open, the `JComboBox`I talk about doesn't have focus, so all is right. If you click on it, its list is delivered just like I want, because the focus owner is the list, not the `JComboBox`, but choosing an item or closing the list without transfer the focus to an other `Component` let the look and feel override my renderer with its default values. – Oliv Nov 26 '20 at 03:25

1 Answers1

0

i don't like that it doesn't respect them when it gains focus.

If you are saying you don't like the blue selection background color when the combo box gains focus then you can use:

UIManager.put("ComboBox.selectionBackground", new ColorUIResource(Color.ORANGE));

This may work on some LAF's. But it will apply for all combo boxes in the application.

If you need it only for a single combo box then you would need to write a custom ComboBoxUI. I have no idea what methods you would need to override, but you can search the source code for "selectionBackground" to see how that property is used.

camickr
  • 321,443
  • 19
  • 166
  • 288
  • I've tried a lot of them (Background, buttonBackground, and more). Pfff. And yeah, i know about restrictions. Some time, it is possible to mix some look and feel, because each call to UIManager methods has only effetcs on the `Components` whose birth are to come. But I don't even do that. I keep the cross-platform look and feel (even if i like Nimbus more) : less problem (and nimbus is very agressive...And about the end of your comment, it's (now) pretty simple to put the default color just like `Color.ORANGE`. – Oliv Nov 26 '20 at 06:48