Search code examples
javastringswingcomboboxopacity

How to set the Opacity of Text in a JComboBox list?


Currently attempting to generate a ComboBox with a list of Strings and want those String values to have a certain opacity. The CombobBox itself should remain normal and only the data change.

I was able accomplish this with my ComboBox of icons by implementing my own custom Class.

    ///This works great when ICons are used within the JComboBox
    class MyImageIconObject extends ImageIcon
    {
        float x;
        ImageIcon ic;
        public MyImageIconObject(String iconLocation)
        {
            super(iconLocation);
            this.ic = new ImageIcon(iconLocation); 
        }
    
        @Override
        public void paintIcon(Component c, Graphics g, int x, int y)
        {
            //super.paintIcon(c, g, x, y);
            ((Graphics2D) g).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.25f));
            ic.paintIcon(c, g, x, y);
            System.out.println("Painting 2");
        }
    }

The above code generates the following results.

enter image description here

Can't do this for Strings since it is a Final class, but even if I could there isn't a paint() type function to override.

import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;

import javax.swing.ImageIcon;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;


public class JComboBoxWithStrings extends JFrame
{
    private JComboBox comboBox;
    JPanel topPanel;
    String[] arrayOfStrings = {"String 1", "Entry 2", "More data", "Entry 10000"};
    
    public JComboBoxWithStrings ()
    {
        
    }
    
    public static void main(String[] args)  
    {

        JComboBoxWithStrings T = new JComboBoxWithStrings();
        T.createGUI();
        T.setVisible(true);        
    }
    public void createGUI(){

        setMinimumSize(new Dimension(500,500));
        setTitle("Demo");
        setLocation(200, 200);

        topPanel = new JPanel();
        getContentPane().add(topPanel, BorderLayout.CENTER);

        comboBox = new JComboBox(arrayOfStrings);
        
        topPanel.add(comboBox);

        super.addWindowListener(new WindowAdapter() {           
            public void windowClosing(WindowEvent e) {              
                dispose();          
            }           
        }); 
    }
}

The above code generates the following :

enter image description here

What is required so that I am able to control the opacity of the Strings displayed in the ComboBox while keeping the ComboBox itself normal?


Solution

  • control the opacity of the Strings displayed in the ComboBox while keeping the ComboBox itself normal?

    Use a custom renderer that checks if the rendering is for the dropdown or the combobox:

    import java.awt.*;
    import javax.swing.*;
    import javax.swing.border.*;
    import javax.swing.plaf.basic.*;
    
    public class ComboBoxTransparent extends JFrame
    {
        public ComboBoxTransparent()
        {
            Object[] items = { Color.red, Color.green, Color.blue };
            JComboBox comboBox = new JComboBox( items );
            comboBox.setRenderer( new TransparentRenderer() );
            getContentPane().add( comboBox, BorderLayout.NORTH );
            add( new JTextField(), BorderLayout.SOUTH);
        }
    
        public static void main(String[] args)
        {
            ComboBoxTransparent frame = new ComboBoxTransparent();
            frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
            frame.pack();
            frame.setLocationRelativeTo( null );
            frame.setVisible( true );
        }
    
        class TransparentRenderer extends BasicComboBoxRenderer
        {
            private Color transparent = new Color(0, 0, 0, 128);
    
            public Component getListCellRendererComponent(
                JList list, Object value, int index, boolean isSelected, boolean cellHasFocus)
            {
                super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
    
                if (index == -1)
                    setForeground( Color.BLACK );
                else
                    setForeground( transparent );
    
                return this;
            }
        }
    }