Search code examples
javaswingjcomboboxtostring

How to change format of color in JComboBox?


I am training a GUI and am facing a string formatting problem. Don't understand how to display the colors in the list in a user-readable format?

  public static void main(String[] args) {

        JFrame jframe = getFrame();

        jframe.setTitle("Background color");

        Toolkit toolkit = Toolkit.getDefaultToolkit();

        Dimension dimension = toolkit.getScreenSize();

        jframe.setBounds(dimension.width/2-250, dimension.height/2-150, 500, 300);

        JPanel jpanel = new JPanel();

        JButton setColor = new JButton("Set Color");

        Color colors[] = {Color.red, Color.green, Color.blue, Color.black};
        
        JComboBox<Color> selector = new JComboBox<>(colors);

        setColor.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                jpanel.setBackground((Color)selector.getSelectedItem());
            }
        });

        jpanel.add(selector);

        jpanel.add(setColor);

        jframe.add(jpanel);
        
      }

      public static JFrame getFrame() {
        JFrame jframe = new JFrame();
        jframe.setVisible(true);
        jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        return jframe;
      }
  }

And here my output:

So, I want the name of the color to be displayed instead of java.awt.Color[.....]

https://i.sstatic.net/UyO9B.png

Thanks in advance!


Solution

  • By default, JComboBox displays the value returned by the toString method of the objects in its list. Since your JComboBox contains Color objects, you see the value returned by method toString of class java.awt.Color.

    If you want to display a color name, then you need to create a custom class that stores both the name of the color, as a String and the Color object. Then you need to override the toString method of the custom class to return just the name of the color. In the below code, the custom class is named NamedColor.

    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Toolkit;
    
    import javax.swing.JButton;
    import javax.swing.JComboBox;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    
    public class ColorSet {
    
        public static void main(String[] args) {
            JFrame jframe = new JFrame("Background color");
            jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            Toolkit toolkit = Toolkit.getDefaultToolkit();
            Dimension dimension = toolkit.getScreenSize();
            jframe.setBounds(dimension.width / 2 - 250, dimension.height / 2 - 150, 500, 300);
            JPanel jpanel = new JPanel();
            JButton setColor = new JButton("Set Color");
            NamedColor colors[] = {new NamedColor(Color.red, "RED"),
                                   new NamedColor(Color.green, "GREEN"),
                                   new NamedColor(Color.blue, "BLUE"),
                                   new NamedColor(Color.black, "BLACK")};
            JComboBox<NamedColor> selector = new JComboBox<>(colors);
            setColor.addActionListener(
                      e -> jpanel.setBackground(((NamedColor) selector.getSelectedItem()).getColor()));
            jpanel.add(selector);
            jpanel.add(setColor);
            jframe.add(jpanel);
            jframe.setVisible(true);
        }
    }
    
    class NamedColor {
        private Color color;
        private String name;
    
        public NamedColor(Color color, String name) {
            this.color = color;
            this.name = name;
        }
    
        public Color getColor() {
            return color;
        }
    
        public String toString() {
            return name;
        }
    }
    

    Notes regarding above code.

    • The ActionListener interface is implemented using a lambda expression
    • You should call method setVisible, of class JFrame only after you have added all the components.