source: josm/trunk/src/org/openstreetmap/josm/gui/widgets/AutoCompleteComboBox.java@ 2281

Last change on this file since 2281 was 2281, checked in by Gubaer, 15 years ago

see #3668: Upload dialog: comment textbox buggy

  • Property svn:eol-style set to native
File size: 4.4 KB
Line 
1// License: GPL. Copyright 2007 by Immanuel Scholz and others
2package org.openstreetmap.josm.gui.widgets;
3
4import java.awt.event.FocusEvent;
5import java.awt.event.FocusListener;
6import java.util.Collection;
7
8import javax.swing.ComboBoxModel;
9import javax.swing.DefaultComboBoxModel;
10import javax.swing.JComboBox;
11import javax.swing.text.AttributeSet;
12import javax.swing.text.BadLocationException;
13import javax.swing.text.JTextComponent;
14import javax.swing.text.PlainDocument;
15
16/**
17 * @author guilhem.bonnefille@gmail.com
18 */
19public class AutoCompleteComboBox extends JComboBox {
20
21
22 private boolean autocompleteEnabled = true;
23
24 /**
25 * Auto-complete a JComboBox.
26 *
27 * Inspired by http://www.orbital-computer.de/JComboBox/
28 */
29 class AutoCompleteComboBoxDocument extends PlainDocument {
30 private JComboBox comboBox;
31 private boolean selecting = false;
32
33 public AutoCompleteComboBoxDocument(final JComboBox comboBox) {
34 this.comboBox = comboBox;
35 }
36
37 @Override public void remove(int offs, int len) throws BadLocationException {
38 if (selecting)
39 return;
40 super.remove(offs, len);
41 }
42
43 @Override public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
44 if(selecting || (offs == 0 && str.equals(getText(0, getLength()))))
45 return;
46 boolean initial = (offs == 0 && getLength() == 0 && str.length() > 1);
47 super.insertString(offs, str, a);
48
49 // return immediately when selecting an item
50 // Note: this is done after calling super method because we need
51 // ActionListener informed
52 if (selecting)
53 return;
54 if (!autocompleteEnabled)
55 return;
56
57 int size = getLength();
58 int start = offs+str.length();
59 int end = start;
60 String curText = getText(0, size);
61 // lookup and select a matching item
62 Object item = lookupItem(curText);
63 setSelectedItem(item);
64 if(initial) {
65 start = 0;
66 }
67 if (item != null) {
68 String newText = item.toString();
69 if(!newText.equals(curText))
70 {
71 selecting = true;
72 super.remove(0, size);
73 super.insertString(0, newText, a);
74 selecting = false;
75 start = size;
76 end = getLength();
77 }
78 }
79 JTextComponent editor = (JTextComponent)comboBox.getEditor().getEditorComponent();
80 editor.setSelectionStart(start);
81 editor.setSelectionEnd(end);
82 }
83
84 private void setSelectedItem(Object item) {
85 selecting = true;
86 comboBox.setSelectedItem(item);
87 selecting = false;
88 }
89
90 private Object lookupItem(String pattern) {
91 ComboBoxModel model = comboBox.getModel();
92 for (int i = 0, n = model.getSize(); i < n; i++) {
93 Object currentItem = model.getElementAt(i);
94 if (currentItem.toString().startsWith(pattern))
95 return currentItem;
96 }
97 return null;
98 }
99 }
100
101 public AutoCompleteComboBox() {
102 final JTextComponent editor = (JTextComponent) this.getEditor().getEditorComponent();
103 editor.setDocument(new AutoCompleteComboBoxDocument(this));
104 editor.addFocusListener(
105 new FocusListener() {
106 public void focusLost(FocusEvent e) {
107 }
108 public void focusGained(FocusEvent e) {
109 editor.selectAll();
110 }
111 }
112 );
113 }
114
115 public void setPossibleItems(Collection<String> elems) {
116 DefaultComboBoxModel model = (DefaultComboBoxModel)this.getModel();
117 Object oldValue = this.getEditor().getItem();
118 model.removeAllElements();
119 for (String elem : elems) {
120 model.addElement(elem);
121 }
122 this.getEditor().setItem(oldValue);
123 }
124
125 protected boolean isAutocompleteEnabled() {
126 return autocompleteEnabled;
127 }
128
129 protected void setAutocompleteEnabled(boolean autocompleteEnabled) {
130 this.autocompleteEnabled = autocompleteEnabled;
131 }
132}
Note: See TracBrowser for help on using the repository browser.