Disabling some of the elements in a JComboBox

We wrap a JComboBox element in our ConditionalItem object that includes a boolean variable isEnabled. Now, in order to change the default behavior of the JComboBox, we need to handle two things: first blur out the elements that are disabled using our own renderer and second ensure the disabled elements cannot be selected by adding a ActionListener that selects the old selected element in case a disabled item was selected.

Main.java:

import javax.swing.plaf.basic.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.awt.*;
    
public class Main extends JFrame
{ 
   public Main() {
      getContentPane().setLayout(new FlowLayout());
      
      final JComboBox combobox = 
         new JComboBox(
            new ConditionalItem[] { 
               new ConditionalItem("Item 1"),
               new ConditionalItem("Item 2", false),
               new ConditionalItem("Item 3", false),
               new ConditionalItem("Item 4")
            }
         );
 
      getContentPane().add(combobox);
      combobox.setRenderer(new ConditionalComboBoxRenderer());
      combobox.addActionListener(new ConditionalComboBoxListener(combobox));
  
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(1);
         }
      });      
   
      setSize(new Dimension(200, 200));
   } 
 
   public static void main(String[] args) throws Exception {
      Main main = new Main();
      main.setVisible(true);
   }
}
 
class ConditionalComboBoxRenderer extends BasicComboBoxRenderer implements ListCellRenderer
{
   public Component getListCellRendererComponent(JList list, 
           Object value, int index, boolean isSelected, boolean cellHasFocus) {
      if (isSelected) {
        setBackground(list.getSelectionBackground());
        setForeground(list.getSelectionForeground());
      } else {
        setBackground(list.getBackground());
        setForeground(list.getForeground());
      } 
 
      if (!((Conditionable) value).isEnabled()) {
        setBackground(list.getBackground());
        setForeground(UIManager.getColor("Label.disabledForeground"));
      }
 
      setFont(list.getFont());
      setText((value == null) ? "" : value.toString());
      return this;
   }  
}
 
class ConditionalComboBoxListener implements ActionListener {
   JComboBox combobox;
   Object oldItem;
    
   ConditionalComboBoxListener(JComboBox combobox) {
      this.combobox = combobox;
      combobox.setSelectedIndex(0);
      oldItem = combobox.getSelectedItem();
   }
    
   public void actionPerformed(ActionEvent e) {
      Object selectedItem = combobox.getSelectedItem();
      if (!((Conditionable) selectedItem).isEnabled()) {
         combobox.setSelectedItem(oldItem);
      } else {
         oldItem = selectedItem;
      }
   }
}
 
class ConditionalItem implements Conditionable {
   Object  object;
   boolean isEnabled;
    
   ConditionalItem(Object object, boolean isEnabled) {
      this.object = object;
      this.isEnabled = isEnabled;
   }
    
   ConditionalItem(Object object) {
     this(object, true);
   }
   
   public boolean isEnabled() {
      return isEnabled;
   }
    
   public void setEnabled(boolean isEnabled) {
      this.isEnabled = isEnabled;
   }
    
   public String toString() {
      return object.toString();
   }
}
 
interface Conditionable {
   public boolean isEnabled();
   public void setEnabled(boolean enabled);
   public String toString();
}