source: josm/trunk/src/org/openstreetmap/josm/gui/tagging/AutoCompletingTextField.java@ 2048

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

Improved auto completion
fixed #2729: Auto completion with numbers sometimes annoying (only fixed in presets, relation editor, not in property dialog)
fixed #2320: Preset dialog for house numbers should have autocompletion (auto completion now supported in all preset dialogs)

File size: 5.8 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.tagging;
3
4import java.awt.Component;
5import java.awt.event.FocusAdapter;
6import java.awt.event.FocusEvent;
7import java.awt.event.KeyAdapter;
8import java.awt.event.KeyEvent;
9import java.util.logging.Logger;
10
11import javax.swing.ComboBoxEditor;
12import javax.swing.JTextField;
13import javax.swing.text.AttributeSet;
14import javax.swing.text.BadLocationException;
15import javax.swing.text.Document;
16import javax.swing.text.PlainDocument;
17
18import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionList;
19
20/**
21 * AutoCompletingTextField is an text field with autocompletion behaviour. It
22 * can be used as table cell editor in {@see JTable}s.
23 *
24 * Autocompletion is controlled by a list of {@see AutoCompletionListItem}s
25 * managed in a {@see AutoCompletionList}.
26 *
27 *
28 */
29public class AutoCompletingTextField extends JTextField implements ComboBoxEditor {
30
31 static private Logger logger = Logger.getLogger(AutoCompletingTextField.class.getName());
32
33 /**
34 * The document model for the editor
35 */
36 class AutoCompletionDocument extends PlainDocument {
37
38 /**
39 * inserts a string at a specific position
40 *
41 */
42 @Override
43 public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
44 if (autoCompletionList == null) {
45 super.insertString(offs, str, a);
46 return;
47 }
48
49 // if the current offset isn't at the end of the document we don't autocomplete.
50 // If a highlighted autocompleted suffix was present and we get here Swing has
51 // already removed it from the document. getLength() therefore doesn't include the
52 // autocompleted suffix.
53 //
54 if (offs < getLength()) {
55 super.insertString(offs, str, a);
56 return;
57 }
58
59 String currentText = getText(0, getLength());
60 // if the text starts with a number we don't autocomplete
61 //
62 try {
63 Long.parseLong(str);
64 if (currentText.length() == 0) {
65 // we don't autocomplete on numbers
66 super.insertString(offs, str, a);
67 return;
68 }
69 Long.parseLong(currentText);
70 super.insertString(offs, str, a);
71 return;
72 } catch(NumberFormatException e) {
73 // either the new text or the current text isn't a number. We continue with
74 // autocompletion
75 }
76 String prefix = currentText.substring(0, offs);
77 autoCompletionList.applyFilter(prefix+str);
78 if (autoCompletionList.getFilteredSize()>0) {
79 // there are matches. Insert the new text and highlight the
80 // auto completed suffix
81 //
82 String matchingString = autoCompletionList.getFilteredItem(0).getValue();
83 remove(0,getLength());
84 super.insertString(0,matchingString,a);
85
86 // highlight from end to insert position
87 //
88 setCaretPosition(getLength());
89 moveCaretPosition(offs + str.length());
90 } else {
91 // there are no matches. Insert the new text, do not highlight
92 //
93 String newText = prefix + str;
94 remove(0,getLength());
95 super.insertString(0,newText,a);
96 setCaretPosition(getLength());
97
98 }
99 }
100 }
101
102 /** the auto completion list user input is matched against */
103 protected AutoCompletionList autoCompletionList = null;
104
105 /**
106 * creates the default document model for this editor
107 *
108 */
109 @Override
110 protected Document createDefaultModel() {
111 return new AutoCompletionDocument();
112 }
113
114 protected void init() {
115 addFocusListener(
116 new FocusAdapter() {
117 @Override public void focusGained(FocusEvent e) {
118 selectAll();
119 applyFilter(getText());
120 }
121 }
122 );
123
124 addKeyListener(
125 new KeyAdapter() {
126
127 @Override
128 public void keyReleased(KeyEvent e) {
129 if (getText().equals("")) {
130 applyFilter("");
131 }
132 }
133 }
134 );
135 }
136
137 /**
138 * constructor
139 */
140 public AutoCompletingTextField() {
141 init();
142 }
143
144 public AutoCompletingTextField(int columns) {
145 super(columns);
146 init();
147 }
148
149 protected void applyFilter(String filter) {
150 if (autoCompletionList != null) {
151 autoCompletionList.applyFilter(filter);
152 }
153 }
154
155 /**
156 *
157 * @return the auto completion list; may be null, if no auto completion list is set
158 */
159 public AutoCompletionList getAutoCompletionList() {
160 return autoCompletionList;
161 }
162
163 /**
164 * sets the auto completion list
165 * @param autoCompletionList the auto completion list; if null, auto completion is
166 * disabled
167 */
168 public void setAutoCompletionList(AutoCompletionList autoCompletionList) {
169 this.autoCompletionList = autoCompletionList;
170 }
171
172 public Component getEditorComponent() {
173 return this;
174 }
175
176 public Object getItem() {
177 return getText();
178 }
179
180 public void setItem(Object anObject) {
181 if (anObject == null) {
182 setText("");
183 } else {
184 setText(anObject.toString());
185 }
186
187 }
188
189
190}
Note: See TracBrowser for help on using the repository browser.