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

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

new: rewrite of CombineWay action
new: conflict resolution dialog for CombineWay, including conflicts for different relation memberships
cleanup: cleanup in OsmReader, reduces memory footprint and reduces parsing time
cleanup: made most of the public fields in OsmPrimitive @deprecated, added accessors and changed the code
cleanup: replaced usages of @deprecated constructors for ExtendedDialog
fixed #3208: Combine ways brokes relation order

WARNING: this changeset touches a lot of code all over the code base. "latest" might become slightly unstable in the next days. Also experience incompatibility issues with plugins in the next few days.

File size: 7.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.ArrayList;
10import java.util.EventObject;
11import java.util.LinkedList;
12import java.util.List;
13import java.util.logging.Logger;
14
15import javax.swing.ComboBoxEditor;
16import javax.swing.JTable;
17import javax.swing.JTextField;
18import javax.swing.event.CellEditorListener;
19import javax.swing.event.ChangeEvent;
20import javax.swing.table.TableCellEditor;
21import javax.swing.text.AttributeSet;
22import javax.swing.text.BadLocationException;
23import javax.swing.text.Document;
24import javax.swing.text.PlainDocument;
25
26import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionList;
27import org.openstreetmap.josm.gui.util.TableCellEditorSupport;
28
29/**
30 * AutoCompletingTextField is an text field with autocompletion behaviour. It
31 * can be used as table cell editor in {@see JTable}s.
32 *
33 * Autocompletion is controlled by a list of {@see AutoCompletionListItem}s
34 * managed in a {@see AutoCompletionList}.
35 *
36 *
37 */
38public class AutoCompletingTextField extends JTextField implements ComboBoxEditor, TableCellEditor {
39
40 static private Logger logger = Logger.getLogger(AutoCompletingTextField.class.getName());
41
42 /**
43 * The document model for the editor
44 */
45 class AutoCompletionDocument extends PlainDocument {
46
47 /**
48 * inserts a string at a specific position
49 *
50 */
51 @Override
52 public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
53 if (autoCompletionList == null) {
54 super.insertString(offs, str, a);
55 return;
56 }
57
58 // if the current offset isn't at the end of the document we don't autocomplete.
59 // If a highlighted autocompleted suffix was present and we get here Swing has
60 // already removed it from the document. getLength() therefore doesn't include the
61 // autocompleted suffix.
62 //
63 if (offs < getLength()) {
64 super.insertString(offs, str, a);
65 return;
66 }
67
68 String currentText = getText(0, getLength());
69 // if the text starts with a number we don't autocomplete
70 //
71 try {
72 Long.parseLong(str);
73 if (currentText.length() == 0) {
74 // we don't autocomplete on numbers
75 super.insertString(offs, str, a);
76 return;
77 }
78 Long.parseLong(currentText);
79 super.insertString(offs, str, a);
80 return;
81 } catch(NumberFormatException e) {
82 // either the new text or the current text isn't a number. We continue with
83 // autocompletion
84 }
85 String prefix = currentText.substring(0, offs);
86 autoCompletionList.applyFilter(prefix+str);
87 if (autoCompletionList.getFilteredSize()>0) {
88 // there are matches. Insert the new text and highlight the
89 // auto completed suffix
90 //
91 String matchingString = autoCompletionList.getFilteredItem(0).getValue();
92 remove(0,getLength());
93 super.insertString(0,matchingString,a);
94
95 // highlight from end to insert position
96 //
97 setCaretPosition(getLength());
98 moveCaretPosition(offs + str.length());
99 } else {
100 // there are no matches. Insert the new text, do not highlight
101 //
102 String newText = prefix + str;
103 remove(0,getLength());
104 super.insertString(0,newText,a);
105 setCaretPosition(getLength());
106
107 }
108 }
109 }
110
111 /** the auto completion list user input is matched against */
112 protected AutoCompletionList autoCompletionList = null;
113
114 /**
115 * creates the default document model for this editor
116 *
117 */
118 @Override
119 protected Document createDefaultModel() {
120 return new AutoCompletionDocument();
121 }
122
123 protected void init() {
124 addFocusListener(
125 new FocusAdapter() {
126 @Override public void focusGained(FocusEvent e) {
127 selectAll();
128 applyFilter(getText());
129 }
130 }
131 );
132
133 addKeyListener(
134 new KeyAdapter() {
135
136 @Override
137 public void keyReleased(KeyEvent e) {
138 if (getText().equals("")) {
139 applyFilter("");
140 }
141 }
142 }
143 );
144 tableCellEditorSupport = new TableCellEditorSupport(this);
145 }
146
147 /**
148 * constructor
149 */
150 public AutoCompletingTextField() {
151 init();
152 }
153
154 public AutoCompletingTextField(int columns) {
155 super(columns);
156 init();
157 }
158
159 protected void applyFilter(String filter) {
160 if (autoCompletionList != null) {
161 autoCompletionList.applyFilter(filter);
162 }
163 }
164
165 /**
166 *
167 * @return the auto completion list; may be null, if no auto completion list is set
168 */
169 public AutoCompletionList getAutoCompletionList() {
170 return autoCompletionList;
171 }
172
173 /**
174 * sets the auto completion list
175 * @param autoCompletionList the auto completion list; if null, auto completion is
176 * disabled
177 */
178 public void setAutoCompletionList(AutoCompletionList autoCompletionList) {
179 this.autoCompletionList = autoCompletionList;
180 }
181
182 public Component getEditorComponent() {
183 return this;
184 }
185
186 public Object getItem() {
187 return getText();
188 }
189
190 public void setItem(Object anObject) {
191 if (anObject == null) {
192 setText("");
193 } else {
194 setText(anObject.toString());
195 }
196
197 }
198
199 /* ------------------------------------------------------------------------------------ */
200 /* TableCellEditor interface */
201 /* ------------------------------------------------------------------------------------ */
202
203 private TableCellEditorSupport tableCellEditorSupport;
204 private String originalValue;
205
206 public void addCellEditorListener(CellEditorListener l) {
207 tableCellEditorSupport.addCellEditorListener(l);
208 }
209
210 protected void rememberOriginalValue(String value) {
211 this.originalValue = value;
212 }
213
214 protected void restoreOriginalValue() {
215 setText(originalValue);
216 }
217
218 public void removeCellEditorListener(CellEditorListener l) {
219 tableCellEditorSupport.removeCellEditorListener(l);
220 }
221 public void cancelCellEditing() {
222 restoreOriginalValue();
223 tableCellEditorSupport.fireEditingCanceled();
224
225 }
226
227 public Object getCellEditorValue() {
228 return getText();
229 }
230
231 public boolean isCellEditable(EventObject anEvent) {
232 return true;
233 }
234
235
236 public boolean shouldSelectCell(EventObject anEvent) {
237 return true;
238 }
239
240 public boolean stopCellEditing() {
241 tableCellEditorSupport.fireEditingStopped();
242 return true;
243 }
244
245 public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
246 setText( value == null ? "" : value.toString());
247 rememberOriginalValue(getText());
248 return this;
249 }
250}
Note: See TracBrowser for help on using the repository browser.