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

4 May 2010

JCombobox with disabled items

Filed under: Java — Raging Goblin @ 13:21
Tags: , ,

I saw a couple of posts (here and here) about a common problem in Java: creating a JCombobox with some items disabled. To give an idea to what I mean here is a screenshot. It shows a JCombobox with some items in gray that cannot be chosen:

DisabledComboboxItem

Here is my solution to this:

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.BasicComboBoxRenderer;

public class DisabledItemsComboboxDemo extends JFrame {

 public static void main(String[] args) {
  DisabledItemsComboboxDemo frame
    = new DisabledItemsComboboxDemo("Combobox with disabled items");
  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");
  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;
   }
  }
 }
}

Blog at WordPress.com.