9 Replies Latest reply: Nov 4, 2013 7:59 AM by mKorbel RSS

    Can't render background color in JComboBox, after selection.

    834336
      I don't understand why this problem is so difficult. It is driving me nuts.

      If I create a renderer for a Jcombobox, it will correctly render TEXT and COLOR if it is displaying it in the pop up list, but as soon as it has been selected, the combo will render TEXT correctly but will ignore COLOR. I have tried playing around with opacity and with the editors, but it just seems as if JComboBox renderers do not work 100% as expected.

      Here is my text code. All I want is for the color of X or Y to be reflected in the selected element :
       
      
      
       import java.awt.BorderLayout;
      import java.awt.Color;
      import java.awt.Component;
      
      import javax.swing.DefaultListCellRenderer;
      import javax.swing.JComboBox;
      import javax.swing.JFrame;
      import javax.swing.JLabel;
      import javax.swing.JList;
      import javax.swing.JPanel;
      
      public class CustomComboBoxDemo extends JPanel {
       
          public CustomComboBoxDemo() {
               
              super(new BorderLayout());
       
              String[] s = { "1", "2", "3", "4", "5" };
              
              JComboBox c = new JComboBox(s);
              JComboBox c2 = new JComboBox(s);
              
              c.setOpaque(true);
              
              ComboBoxRenderer renderer= new ComboBoxRenderer();
              c.setRenderer(renderer);
              c2.setRenderer(renderer);
       
              JPanel p = new JPanel();
              p.add(c);
              p.add(c2);
              
              add(p);
          }
      
       
          class ComboBoxRenderer extends DefaultListCellRenderer {
       
              public ComboBoxRenderer() {
                  setOpaque(true);
              }
      
              public Component getListCellRendererComponent(
                                                 JList list,
                                                 Object value,
                                                 int index,
                                                 boolean isSelected,
                                                 boolean cellHasFocus) {
      
                   JLabel c = (JLabel)super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
                   
                   if (value.toString().equals("3")) {
                       c.setText("X");
                       c.setBackground(Color.RED);
                   } else {
                       c.setText("Y");
                       c.setBackground(Color.GREEN);
                   }
                   
                   return this;
              }
          }
          
          public static void main(String[] args) {
              javax.swing.SwingUtilities.invokeLater(new Runnable() {
                  public void run() {
                      createAndShowGUI();
                  }
              });
          }
          
          private static void createAndShowGUI() {
              //Create and set up the window.
              JFrame frame = new JFrame("CustomComboBoxDemo");
              frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              frame.setContentPane(new CustomComboBoxDemo());
       
              //Display the window.
              frame.pack();
              frame.setVisible(true);
          }
      }
        • 1. Re: Can't render background color in JComboBox, after selection.
          898886
          Hi,

          If you want to change background color on selection of item then you should use

          list.setSelectionBackground(color);

          Rupali
          • 2. Re: Can't render background color in JComboBox, after selection.
            StanislavL
            BasicComboBoxUI has the method
                public void paintCurrentValue(Graphics g,Rectangle bounds,boolean hasFocus) {
                    ListCellRenderer renderer = comboBox.getRenderer();
                    Component c;
            
                    if ( hasFocus && !isPopupVisible(comboBox) ) {
                        c = renderer.getListCellRendererComponent( listBox,
                                                                   comboBox.getSelectedItem(),
                                                                   -1,
                                                                   true,
                                                                   false );
                    }
                    else {
                        c = renderer.getListCellRendererComponent( listBox,
                                                                   comboBox.getSelectedItem(),
                                                                   -1,
                                                                   false,
                                                                   false );
                        c.setBackground(UIManager.getColor("ComboBox.background"));
                    }
                    c.setFont(comboBox.getFont());
                    if ( hasFocus && !isPopupVisible(comboBox) ) {
                        c.setForeground(listBox.getSelectionForeground()); //your code reset after set in renderer. <--------
                        c.setBackground(listBox.getSelectionBackground());
                    }
                    else {
                        if ( comboBox.isEnabled() ) {
                            c.setForeground(comboBox.getForeground());
                            c.setBackground(comboBox.getBackground());
                        }
                        else {
                            c.setForeground(DefaultLookup.getColor(
                                     comboBox, this, "ComboBox.disabledForeground", null));
                            c.setBackground(DefaultLookup.getColor(
                                     comboBox, this, "ComboBox.disabledBackground", null));
                        }
                    }
            
                    // Fix for 4238829: should lay out the JPanel.
                    boolean shouldValidate = false;
                    if (c instanceof JPanel)  {
                        shouldValidate = true;
                    }
            
                    int x = bounds.x, y = bounds.y, w = bounds.width, h = bounds.height;
                    if (padding != null) {
                        x = bounds.x + padding.left;
                        y = bounds.y + padding.top;
                        w = bounds.width - (padding.left + padding.right);
                        h = bounds.height - (padding.top + padding.bottom);
                    }
                    
                    currentValuePane.paintComponent(g,c,comboBox,x,y,w,h,shouldValidate);
                }
            • 3. Re: Can't render background color in JComboBox, after selection.
              834336
              Hi Rupali,

              I am using a JCombobox, not a JList. So that doesnt work
              • 4. Re: Can't render background color in JComboBox, after selection.
                834336
                I also tried :

                combo.getEditor().getEditorComponent().setBackground(Color.GREEN);

                and

                combo.setBackground(Color.PINK) .... but that also changes the color of the arrow button!!!!

                Anyone else have an idea? I am going nuts here.
                • 5. Re: Can't render background color in JComboBox, after selection.
                  834336
                  I think the problem has to do with the Alloy look and feel. If I use the Systsem look and feel then the setBackground() method does not colour in the button (just the textfield)

                  This has fixed my initial problem :
                  import java.awt.BorderLayout;
                  import java.awt.Color;
                  import java.awt.Component;
                  
                  import javax.swing.DefaultListCellRenderer;
                  import javax.swing.JComboBox;
                  import javax.swing.JFrame;
                  import javax.swing.JLabel;
                  import javax.swing.JList;
                  import javax.swing.JPanel;
                  import javax.swing.UIManager;
                  import javax.swing.plaf.basic.BasicComboBoxEditor;
                  
                  public class CustomComboBoxDemo extends JPanel {
                   
                      public CustomComboBoxDemo() {
                           
                          super(new BorderLayout());
                   
                          
                            try {
                                 UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                            } catch (Exception e) {
                                 e.printStackTrace();
                            }
                          
                          String[] s = { "1", "2", "3", "4", "5" };
                          
                          JComboBox c = new JComboBox(s);
                          JComboBox c2 = new JComboBox(s);
                  //        c.setRenderer(aRenderer)
                  //        c.getEditor().getEditorComponent().setBackground(Color.GREEN);
                          
                          c.setBackground(Color.pink);
                          c2.setBackground(Color.pink);
                  //        c2.setBackground(Color.black);
                          
                          c.setOpaque(true);
                          c2.setOpaque(false);
                          
                          ComboBoxRenderer renderer= new ComboBoxRenderer();
                          c.setRenderer(renderer);
                          c2.setRenderer(renderer);
                   
                          JPanel p = new JPanel();
                          p.add(c);
                          p.add(c2);
                          
                          add(p);
                      }
                  
                      private class MyComboBoxEditor extends BasicComboBoxEditor{
                  
                           public Component getEditorComponent(){
                                Component comp = super.getEditorComponent();
                                comp.setBackground(Color.red);
                                return comp;
                           }
                  
                       }
                   
                      class ComboBoxRenderer extends DefaultListCellRenderer {
                   
                          public ComboBoxRenderer() {
                              setOpaque(true);
                          }
                  
                          public Component getListCellRendererComponent(
                                                             JList list,
                                                             Object value,
                                                             int index,
                                                             boolean isSelected,
                                                             boolean cellHasFocus) {
                  
                               JLabel c = (JLabel)super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
                               
                  //             setForeground(Color.green);
                  //             setBackground(Color.black);
                  //             list.setForeground(Color.green);
                  //             list.setBackground(Color.black);
                               
                               
                               if (value.toString().equals("3")) {
                                   c.setText("X");
                                   c.setBackground(Color.RED);
                               } else {
                                   c.setText("Y");
                                   c.setBackground(Color.GREEN);
                               }
                               
                               return this;
                          }
                      }
                      
                      public static void main(String[] args) {
                          javax.swing.SwingUtilities.invokeLater(new Runnable() {
                              public void run() {
                                  createAndShowGUI();
                              }
                          });
                      }
                      
                      private static void createAndShowGUI() {
                          //Create and set up the window.
                          JFrame frame = new JFrame("CustomComboBoxDemo");
                          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                          frame.setContentPane(new CustomComboBoxDemo());
                   
                          //Display the window.
                          frame.pack();
                          frame.setVisible(true);
                      }
                  }
                  • 6. Re: Can't render background color in JComboBox, after selection.
                    834336
                    figured it out myself
                    • 7. Re: Can't render background color in JComboBox, after selection.
                      898886
                      Hi,

                      try to use below code

                      public Component getListCellRendererComponent(
                      JList list,
                      Object value,
                      int index,
                      boolean isSelected,
                      boolean cellHasFocus) {

                           JLabel c = (JLabel)super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);

                           if (value.toString().equals("3")) {
                           c.setText("X");
                           c.setBackground(Color.RED);
                      list.setSelectionBackground(Color.RED); // added by Rupali
                           } else {
                           c.setText("Y");
                           c.setBackground(Color.GREEN);
                      list.setSelectionBackground(Color.GREEN); // added by Rupali
                           }
                      revalidate(); // added by Rupali
                      repaint(); // added by Rupali
                           return this;
                      }


                      --- Rupali
                      • 8. Re: Can't render background color in JComboBox, after selection.
                        04d92dc6-2a78-4164-8f70-de3e2dceae79

                        Great!

                        I got the same problem.

                        Nowhere in the solution evorage.

                        Even in java api.

                        How did you solve it?

                        • 9. Re: Can't render background color in JComboBox, after selection.
                          mKorbel

                          How did you solve it?

                           

                          - for simple selection generated by Mouse or Key Evens to override isSelected and hasFocus, 

                          - for changes from outside (whatever to changed Colors) is required to save in XxxComboBoxModel

                          - quite common Renderers issue, you need to override if (something) .... and with else .... too, concept valid for Renderers concept in Swing (JComboBox, JList, JTable, JTree--> has another two three specifics issues)