Have a lot of items in combo box makes user irritated when running the program, especially when fast input is needed, manual search by scrolling down the scroll bar is so time consuming but can be avoided if we can get what item we want to choose by just write first or second letter of it. In another case you maybe want to make a text field with some suggestion input like search engine text field. To make something like that, we need JTextField and JComboBox together as one.

Custom JComboBox :

import java.awt.event.ItemEvent;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.plaf.basic.BasicComboBoxEditor;

public class AutoComboBox extends JComboBox {
private class AutoTextFieldEditor extends BasicComboBoxEditor {

private AutoTextField getAutoTextFieldEditor() {
return (AutoTextField) editor;
}

AutoTextFieldEditor(java.util.List list) {
editor = new AutoTextField(list, AutoComboBox.this);
}
}

public AutoComboBox(java.util.List list) {
isFired = false;
autoTextFieldEditor = new AutoTextFieldEditor(list);
setEditable(true);
setModel(new DefaultComboBoxModel(list.toArray()) {

protected void fireContentsChanged(Object obj, int i, int j) {
if (!isFired)
super.fireContentsChanged(obj, i, j);
}

});
setEditor(autoTextFieldEditor);
}

public boolean isCaseSensitive() {
return autoTextFieldEditor.getAutoTextFieldEditor().isCaseSensitive();
}

public void setCaseSensitive(boolean flag) {
autoTextFieldEditor.getAutoTextFieldEditor().setCaseSensitive(flag);
}

public boolean isStrict() {
return autoTextFieldEditor.getAutoTextFieldEditor().isStrict();
}

public void setStrict(boolean flag) {
autoTextFieldEditor.getAutoTextFieldEditor().setStrict(flag);
}

public java.util.List getDataList() {
return autoTextFieldEditor.getAutoTextFieldEditor().getDataList();
}

public void setDataList(java.util.List list) {
autoTextFieldEditor.getAutoTextFieldEditor().setDataList(list);
setModel(new DefaultComboBoxModel(list.toArray()));
}

void setSelectedValue(Object obj) {
if (isFired) {
return;
} else {
isFired = true;
setSelectedItem(obj);
fireItemStateChanged(new ItemEvent(this, 701, selectedItemReminder,1));
isFired = false;
return;
}
}

@Override
protected void fireActionEvent() {
if (!isFired)
super.fireActionEvent();
}

private AutoTextFieldEditor autoTextFieldEditor;

private boolean isFired;

}

Custom JTextField :

import java.util.List;
import javax.swing.JTextField;
import javax.swing.text.*;

public class AutoTextField extends JTextField {
 class AutoDocument extends PlainDocument {

public void replace(int i, int j, String s, AttributeSet attributeset)
 throws BadLocationException {
 super.remove(i, j);
 insertString(i, s, attributeset);
 }

public void insertString(int i, String s, AttributeSet attributeset)
 throws BadLocationException {
 if (s == null || "".equals(s))
 return;
 String s1 = getText(0, i);
 String s2 = getMatch(s1 + s);
 int j = (i + s.length()) - 1;
 if (isStrict && s2 == null) {
 s2 = getMatch(s1);
 j--;
 } else if (!isStrict && s2 == null) {
 super.insertString(i, s, attributeset);
 return;
 }
 if (autoComboBox != null && s2 != null)
 autoComboBox.setSelectedValue(s2);
 super.remove(0, getLength());
 super.insertString(0, s2, attributeset);
 setSelectionStart(j + 1);
 setSelectionEnd(getLength());
 }

public void remove(int i, int j) throws BadLocationException {
 int k = getSelectionStart();
 if (k > 0)
 k--;
 String s = getMatch(getText(0, k));
 if (!isStrict && s == null) {
 super.remove(i, j);
 } else {
 super.remove(0, getLength());
 super.insertString(0, s, null);
 }
 if (autoComboBox != null && s != null)
 autoComboBox.setSelectedValue(s);
 try {
 setSelectionStart(k);
 setSelectionEnd(getLength());
 } catch (Exception exception) {
 }
 }

}

public AutoTextField(List list) {
 isCaseSensitive = false;
 isStrict = true;
 autoComboBox = null;
 if (list == null) {
 throw new IllegalArgumentException("values can not be null");
 } else {
 dataList = list;
 init();
 return;
 }
 }

AutoTextField(List list, AutoComboBox b) {
 isCaseSensitive = false;
 isStrict = true;
 autoComboBox = null;
 if (list == null) {
 throw new IllegalArgumentException("values can not be null");
 } else {
 dataList = list;
 autoComboBox = b;
 init();
 return;
 }
 }

private void init() {
 setDocument(new AutoDocument());
 if (isStrict && dataList.size() > 0)
 setText(dataList.get(0).toString());
 }

private String getMatch(String s) {
 for (int i = 0; i < dataList.size(); i++) {
 String s1 = dataList.get(i).toString();
 if (s1 != null) {
 if (!isCaseSensitive
 && s1.toLowerCase().startsWith(s.toLowerCase()))
 return s1;
 if (isCaseSensitive && s1.startsWith(s))
 return s1;
 }
 }

return null;
 }

public void replaceSelection(String s) {
 AutoDocument _lb = (AutoDocument) getDocument();
 if (_lb != null)
 try {
 int i = Math.min(getCaret().getDot(), getCaret().getMark());
 int j = Math.max(getCaret().getDot(), getCaret().getMark());
 _lb.replace(i, j - i, s, null);
 } catch (Exception exception) {
 }
 }

public boolean isCaseSensitive() {
 return isCaseSensitive;
 }

public void setCaseSensitive(boolean flag) {
 isCaseSensitive = flag;
 }

public boolean isStrict() {
 return isStrict;
 }

public void setStrict(boolean flag) {
 isStrict = flag;
 }

public List getDataList() {
 return dataList;
 }

public void setDataList(List list) {
 if (list == null) {
 throw new IllegalArgumentException("values can not be null");
 } else {
 dataList = list;
 return;
 }
 }

private List dataList;

private boolean isCaseSensitive;

private boolean isStrict;

private AutoComboBox autoComboBox;
}

Now here is how to use em :

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.text.*;

public class AutoComplete extends JComboBox implements JComboBox.KeySelectionManager
{
 private String searchFor;
 private long lap;
 public class CBDocument extends PlainDocument
 {
 @Override
 public void insertString(int offset, String str, AttributeSet a) throws BadLocationException
 {
 if (str==null) return;
 super.insertString(offset, str, a);
 if(!isPopupVisible() && str.length() != 0) fireActionEvent();
 }
 }
 public AutoComplete(Object[] items)
 {
 super(items);
 lap = new java.util.Date().getTime();
 setKeySelectionManager(this);
 JTextField tf;
 if(getEditor() != null)
 {
 tf = (JTextField)getEditor().getEditorComponent();
 if(tf != null)
 {
 tf.setDocument(new CBDocument());
 addActionListener(new ActionListener()
 {
 public void actionPerformed(ActionEvent evt)
 {
 JTextField tf = (JTextField)getEditor().getEditorComponent();
 String text = tf.getText();
 ComboBoxModel aModel = getModel();
 String current;
 for(int i = 0; i < aModel.getSize(); i++)
 {
 current = aModel.getElementAt(i).toString();
 if(current.toLowerCase().startsWith(text.toLowerCase()))
 {
 tf.setText(current);
 tf.setSelectionStart(text.length());
 tf.setSelectionEnd(current.length());
 break;
 }
 }
 }
 });
 }
 }
 }
 public int selectionForKey(char aKey, ComboBoxModel aModel)
 {
 long now = new java.util.Date().getTime();
 if (searchFor!=null && aKey==KeyEvent.VK_BACK_SPACE && searchFor.length()>0)
 {
 searchFor = searchFor.substring(0, searchFor.length() -1);
 }
 else
 {
 if(lap + 1000 < now)
 searchFor = "" + aKey;
 else
 searchFor = searchFor + aKey;
 }
 lap = now;
 String current;
 for(int i = 0; i < aModel.getSize(); i++)
 {
 current = aModel.getElementAt(i).toString().toLowerCase();
 if (current.toLowerCase().startsWith(searchFor.toLowerCase())) return i;
 }
 return -1;
 }

 @Override
 public void fireActionEvent()
 {
 super.fireActionEvent();
 }

public static void main(String arg[])
 {
 JFrame f = new JFrame("AutoCompletion");
 f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 f.setSize(300,100);
 Container cp= f.getContentPane();
 cp.setLayout(new GridLayout(2, 1));

 Locale[] locales = Locale.getAvailableLocales();
 //JComboBox 1 allowing any input
 JComboBox cBox= new AutoComplete(locales);

 java.util.List<String> items = new ArrayList<String>(){};
 for (int i = 0; i < locales.length; i++) {
 items.add(locales[i].toString());
 }

//JComboBox 2 with strict input
 JComboBox cBox2 = new AutoComboBox(items);
 cBox.setBounds(50,50,100,21);
 cBox.setEditable(true);
 cp.add(cBox);
 cp.add(cBox2);
 f.setVisible(true);
 f.setResizable(false);
 f.setLocationRelativeTo(null);
 }
}

Combo box 1 will become text field like you can found in search engine, when you write something inside of the text field, it will give you suggestion based on item of combo box which have common letter sequence. Combo box 2 also like search engine text field but strictly only allowing write something that exist in combo box item.

Subscribe & fast response :