1 | // License: GPL. Copyright 2007 by Immanuel Scholz and others
|
---|
2 | package org.openstreetmap.josm.tools;
|
---|
3 |
|
---|
4 | import java.util.Collection;
|
---|
5 |
|
---|
6 | import javax.swing.ComboBoxModel;
|
---|
7 | import javax.swing.DefaultComboBoxModel;
|
---|
8 | import javax.swing.JComboBox;
|
---|
9 | import javax.swing.text.AttributeSet;
|
---|
10 | import javax.swing.text.BadLocationException;
|
---|
11 | import javax.swing.text.JTextComponent;
|
---|
12 | import javax.swing.text.PlainDocument;
|
---|
13 |
|
---|
14 | /**
|
---|
15 | * @author guilhem.bonnefille@gmail.com
|
---|
16 | */
|
---|
17 | public class AutoCompleteComboBox extends JComboBox {
|
---|
18 |
|
---|
19 | /**
|
---|
20 | * Auto-complete a JComboBox.
|
---|
21 | *
|
---|
22 | * Inspired by http://www.orbital-computer.de/JComboBox/
|
---|
23 | */
|
---|
24 | private class AutoCompleteComboBoxDocument extends PlainDocument {
|
---|
25 | private JComboBox comboBox;
|
---|
26 | private boolean selecting = false;
|
---|
27 |
|
---|
28 | public AutoCompleteComboBoxDocument(final JComboBox comboBox) {
|
---|
29 | this.comboBox = comboBox;
|
---|
30 | }
|
---|
31 |
|
---|
32 | @Override public void remove(int offs, int len) throws BadLocationException {
|
---|
33 | if (selecting)
|
---|
34 | return;
|
---|
35 | super.remove(offs, len);
|
---|
36 | }
|
---|
37 |
|
---|
38 | @Override public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
|
---|
39 | super.insertString(offs, str, a);
|
---|
40 |
|
---|
41 | // return immediately when selecting an item
|
---|
42 | // Nota: this is done after calling super method because we need
|
---|
43 | // ActionListener informed
|
---|
44 | if (selecting)
|
---|
45 | return;
|
---|
46 |
|
---|
47 | // lookup and select a matching item
|
---|
48 | Object item = lookupItem(getText(0, getLength()));
|
---|
49 | if (item != null) {
|
---|
50 | // remove all text and insert the completed string
|
---|
51 | super.remove(0, getLength());
|
---|
52 | super.insertString(0, item.toString(), a);
|
---|
53 | // select the completed part
|
---|
54 | JTextComponent editor = (JTextComponent)comboBox.getEditor().getEditorComponent();
|
---|
55 | editor.setSelectionStart(offs + str.length());
|
---|
56 | editor.setSelectionEnd(getLength());
|
---|
57 | }
|
---|
58 | setSelectedItem(item);
|
---|
59 | }
|
---|
60 |
|
---|
61 | private void setSelectedItem(Object item) {
|
---|
62 | selecting = true;
|
---|
63 | comboBox.setSelectedItem(item);
|
---|
64 | selecting = false;
|
---|
65 | }
|
---|
66 |
|
---|
67 | private Object lookupItem(String pattern) {
|
---|
68 | ComboBoxModel model = comboBox.getModel();
|
---|
69 | for (int i = 0, n = model.getSize(); i < n; i++) {
|
---|
70 | Object currentItem = model.getElementAt(i);
|
---|
71 | if (currentItem.toString().startsWith(pattern))
|
---|
72 | return currentItem;
|
---|
73 | }
|
---|
74 | return null;
|
---|
75 | }
|
---|
76 | }
|
---|
77 |
|
---|
78 | public AutoCompleteComboBox() {
|
---|
79 | JTextComponent editor = (JTextComponent) this.getEditor().getEditorComponent();
|
---|
80 | editor.setDocument(new AutoCompleteComboBoxDocument(this));
|
---|
81 | }
|
---|
82 |
|
---|
83 | public void setPossibleItems(Collection<String> elems) {
|
---|
84 | Object oldValue = this.getSelectedItem();
|
---|
85 | DefaultComboBoxModel model = (DefaultComboBoxModel)this.getModel();
|
---|
86 | model.removeAllElements();
|
---|
87 | for (String elem : elems) model.addElement(elem);
|
---|
88 | this.setSelectedItem(oldValue);
|
---|
89 | this.getEditor().selectAll();
|
---|
90 | }
|
---|
91 | }
|
---|