import java.awt.EventQueue; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.Set; import javax.swing.DefaultComboBoxModel; import javax.swing.JComboBox; import javax.swing.JTextField; public class AutoSuggest extends JComboBox { private final JComboBox comboBox = this; private final JTextField textField = (JTextField) getEditor().getEditorComponent(); private final List suggestions = new LinkedList<>(); private boolean hide_flag = false; public AutoSuggest() { super(); setEditable(true); textField.addKeyListener(new KeyAdapter() { @Override public void keyTyped(KeyEvent e) { EventQueue.invokeLater(() -> { String text = textField.getText(); if (text.length() == 0) { comboBox.hidePopup(); setModel(new DefaultComboBoxModel(suggestions.toArray()), ""); } else { DefaultComboBoxModel m = getSuggestedModel(suggestions, text); if (m.getSize() == 0 || hide_flag) { comboBox.hidePopup(); hide_flag = false; } else { setModel(m, text); comboBox.showPopup(); } } }); } @Override public void keyPressed(KeyEvent e) { String text = textField.getText(); int code = e.getKeyCode(); switch (code) { case KeyEvent.VK_ENTER: if (!suggestions.contains(text)) { suggestions.add(text); Collections.sort(suggestions); setModel(getSuggestedModel(suggestions, text), text); } hide_flag = true; break; case KeyEvent.VK_ESCAPE: hide_flag = true; break; case KeyEvent.VK_RIGHT: for (int i = 0; i < suggestions.size(); i++) { String str = suggestions.get(i); if (str.startsWith(text)) { comboBox.setSelectedIndex(-1); textField.setText(str); return; } } break; default: break; } } }); setModel(new DefaultComboBoxModel(suggestions.toArray()), ""); } public void update(Set terms) { textField.setText(""); suggestions.clear(); suggestions.addAll(terms); setModel(new DefaultComboBoxModel(suggestions.toArray()), ""); } private void setModel(DefaultComboBoxModel defaultComboBoxModel, String text) { comboBox.setModel(defaultComboBoxModel); comboBox.setSelectedIndex(-1); textField.setText(text); } private static DefaultComboBoxModel getSuggestedModel(List list, String text) { DefaultComboBoxModel m = new DefaultComboBoxModel(); list.stream().filter((s) -> (s.toLowerCase().startsWith(text.toLowerCase()))).forEach((s) -> { m.addElement(s); }); return m; } public JTextField getTextField() { return textField; } public String getText() { return textField.getText(); } }