Auto complete or search in a JComboBox import java.awt.Component; import java.util.*; import javax.swing.*; import javax.swing.plaf.basic.BasicComboBoxEditor; import javax.swing.text.*; public class AutoCompleteComboBox extends JComboBox { private static final Locale[] INSTALLED_LOCALES = Locale.getAvailableLocales(); private ComboBoxModel model = null; public static void main(String[] args) { JFrame f = new JFrame("AutoCompleteComboBox"); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); AutoCompleteComboBox box = new AutoCompleteComboBox(INSTALLED_LOCALES, false); f.getContentPane().add(box); f.pack(); f.setLocationRelativeTo(null); f.setVisible(true); } /** * Constructor for AutoCompleteComboBox - * The Default Model is a TreeSet which is alphabetically sorted and doesnt allow duplicates. * @param items */ public AutoCompleteComboBox(Object[] items, boolean caseSensitive) { super(items); model = new ComboBoxModel(items); setModel(model); setEditable(true); setEditor(new AutoCompleteEditor(this, caseSensitive)); } /** * Constructor for AutoCompleteComboBox - * The Default Model is a TreeSet which is alphabetically sorted and doesnt allow duplicates. * @param items */ public AutoCompleteComboBox(Vector items, boolean caseSensitive) { super(items); model = new ComboBoxModel(items); setModel(model); setEditable(true); setEditor(new AutoCompleteEditor(this, caseSensitive)); } /** * Constructor for AutoCompleteComboBox - * This constructor uses JComboBox's Default Model which is a Vector. * @param caseSensitive */ public AutoCompleteComboBox(boolean caseSensitive) { super(); setEditable(true); setEditor(new AutoCompleteEditor(this, caseSensitive)); } /* * ComboBoxModel.java */ public class ComboBoxModel extends DefaultComboBoxModel { /** * The TreeSet which holds the combobox's data (ordered no duplicates) */ private TreeSet values = null; public ComboBoxModel(List items) { super(); this.values = new TreeSet(); int i, c; for (i = 0, c = items.size(); i < c; i++) values.add(items.get(i).toString()); Iterator it = values.iterator(); while (it.hasNext()) super.addElement(it.next().toString()); } public ComboBoxModel(final Object items[]) { this(Arrays.asList(items)); } } /* * AutoCompleteEditor.java */ public class AutoCompleteEditor extends BasicComboBoxEditor { private JTextField editor = null; public AutoCompleteEditor(JComboBox combo, boolean caseSensitive) { super(); editor = new AutoCompleteEditorComponent(combo, caseSensitive); } /** * overrides BasicComboBox's getEditorComponent to return custom TextField (AutoCompleteEditorComponent) */ public Component getEditorComponent() { return editor; } } /* * AutoCompleteEditorComponent.java */ public class AutoCompleteEditorComponent extends JTextField { JComboBox combo = null; boolean caseSensitive = false; public AutoCompleteEditorComponent(JComboBox combo, boolean caseSensitive) { super(); this.combo = combo; this.caseSensitive = caseSensitive; } /** * overwritten to return custom PlainDocument which does the work*/ protected Document createDefaultModel() { return new PlainDocument() { public void insertString(int offs, String str, AttributeSet a) throws BadLocationException { if (str == null || str.length() == 0) return; int size = combo.getItemCount(); String text = getText(0, getLength()); for (int i = 0; i < size; i++) { String item = combo.getItemAt(i).toString(); if (getLength() + str.length() > item.length()) continue; if (!caseSensitive) { if ((text + str).equalsIgnoreCase(item)) { combo.setSelectedIndex(i); //if (!combo.isPopupVisible()) // combo.setPopupVisible(true); super.remove(0, getLength()); super.insertString(0, item, a); return; } else if (item.substring(0, getLength() + str.length()).equalsIgnoreCase(text + str)) { combo.setSelectedIndex(i); if (!combo.isPopupVisible()) combo.setPopupVisible(true); super.remove(0, getLength()); super.insertString(0, item, a); return; } } else if (caseSensitive) { if ((text + str).equals(item)) { combo.setSelectedIndex(i); if (!combo.isPopupVisible()) combo.setPopupVisible(true); super.remove(0, getLength()); super.insertString(0, item, a); return; } else if (item.substring(0, getLength() + str.length()).equals(text + str)) { combo.setSelectedIndex(i); if (!combo.isPopupVisible()) combo.setPopupVisible(true); super.remove(0, getLength()); super.insertString(0, item, a); return; } } } } }; } } }