Raging Goblin

17 May 2010

JCombobox with extra items that are not part of the list

Filed under: Java — Raging Goblin @ 18:12
Tags: , ,

In my last post I spoke about a JCombobox with the ability to add disabled items. Today I muse a little more on the JCombobox. This time I wanted to add an item to the JCombobox that is not part of the list with displayed items.

ComboboxExtraItem

JCombobox has a method setSelectedItem(Object anObject) for this. When you call this method with an item that is not part of the list it will only be displayed when the JCombobox is editable, if the JCombobox is not editable it will be ignored completely. So, in order to get an JCombobox to which we can call setSelectedItem(Object anObject) with the provided Object not being part of the list and that is not editable we extend our previous DisabledItemsCombobox with our own ComboBoxEditor. Now the trick is that we set the JCombobox editable property to true, but the editable property of the ComboBoxEditor to false.

import java.awt.Component;
import java.util.HashSet;
import java.util.Set;

import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.UIManager;
import javax.swing.plaf.basic.BasicComboBoxEditor;
import javax.swing.plaf.basic.BasicComboBoxRenderer;

public class DisabledItemsComboboxDemo extends JFrame {

 public static void main(String[] args) {
  DisabledItemsComboboxDemo frame = new DisabledItemsComboboxDemo(
    "Combobox displaying an item that is not part of the list");
  frame.setVisible(true);
 }

 public DisabledItemsComboboxDemo(String title) {
  super(title);
  this.setDefaultCloseOperation(EXIT_ON_CLOSE);
  this.init();
 }

 private void init() {
  this.setSize(500, 50);
  DisabledItemsComboBox box = new DisabledItemsComboBox();
  box.addItem("This item is disabled but selected at first appearance", true);
  box.addItem("This item is disabled and you cannot select it", true);
  box.addItem("This is the first selectable item");
  box.addItem("This is the second selectable item");
  box.addItem("This is the third selectable item");
  MyComboBoxEditor editor = new MyComboBoxEditor();
  box.setEditor(editor);
  box.setEditable(true);
  box.setSelectedItem("This item is not in the list of selectable items");
  add(box);
 }

 private class DisabledItemsComboBox extends JComboBox {

  public DisabledItemsComboBox() {
   super();
   super.setRenderer(new DisabledItemsRenderer());
  }

  private Set disabled_items = new HashSet();

  public void addItem(Object anObject, boolean disabled) {
   super.addItem(anObject);
   if (disabled) {
    disabled_items.add(getItemCount() - 1);
   }
  }

  @Override
  public void removeAllItems() {
   super.removeAllItems();
   disabled_items = new HashSet();
  }

  @Override
  public void removeItemAt(final int anIndex) {
   super.removeItemAt(anIndex);
   disabled_items.remove(anIndex);
  }

  @Override
  public void removeItem(final Object anObject) {
   for (int i = 0; i < getItemCount(); i++) {
    if (getItemAt(i) == anObject) {
     disabled_items.remove(i);
    }
   }
   super.removeItem(anObject);
  }

  @Override
  public void setSelectedIndex(int index) {
   if (!disabled_items.contains(index)) {
    super.setSelectedIndex(index);
   }
  }

  private class DisabledItemsRenderer extends BasicComboBoxRenderer {

   @Override
   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 (disabled_items.contains(index)) {
     setBackground(list.getBackground());
     setForeground(UIManager.getColor("Label.disabledForeground"));
    }
    setFont(list.getFont());
    setText((value == null) ? "" : value.toString());
    return this;
   }
  }
 }

 public class MyComboBoxEditor extends BasicComboBoxEditor {

  public MyComboBoxEditor() {
   editor.setEditable(false);
  }
 }
}
Advertisements

Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Create a free website or blog at WordPress.com.

%d bloggers like this: