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

Last change on this file since 4191 was 4191, checked in by stoecker, 13 years ago

remove old debug stuff

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