source: josm/trunk/src/org/openstreetmap/josm/gui/tagging/ac/AutoCompletionList.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: 8.9 KB
Line 
1package org.openstreetmap.josm.gui.tagging.ac;
2
3import java.util.ArrayList;
4import java.util.Collection;
5import java.util.Collections;
6import java.util.List;
7
8import javax.swing.JTable;
9import javax.swing.table.AbstractTableModel;
10
11/**
12 * AutoCompletionList manages a list of {@see AutoCompletionListItem}s.
13 *
14 * The list is sorted, items with higher priority first, then according to lexicographic order
15 * on the value of the {@see AutoCompletionListItem}.
16 *
17 * AutoCompletionList maintains two views on the list of {@see AutoCompletionListItem}s.
18 * <ol>
19 * <li>the bare, unfiltered view which includes all items</li>
20 * <li>a filtered view, which includes only items which match a current filter expression</li>
21 * </ol>
22 *
23 * AutoCompletionList is an {@link AbstractTableModel} which serves the list of filtered
24 * items to a {@link JTable}.
25 *
26 */
27public class AutoCompletionList extends AbstractTableModel {
28
29 /** the bare list of AutoCompletionItems */
30 private ArrayList<AutoCompletionListItem> list = null;
31 /** the filtered list of AutoCompletionItems */
32 private ArrayList<AutoCompletionListItem> filtered = null;
33 /** the filter expression */
34 private String filter = null;
35
36 /**
37 * constructor
38 */
39 public AutoCompletionList() {
40 list = new ArrayList<AutoCompletionListItem>();
41 filtered = new ArrayList<AutoCompletionListItem>();
42 }
43
44
45 /**
46 * applies a filter expression to the list of {@see AutoCompletionListItem}s.
47 *
48 * The matching criterion is a case insensitive substring match.
49 *
50 * @param filter the filter expression; must not be null
51 *
52 * @exception IllegalArgumentException thrown, if filter is null
53 */
54 public void applyFilter(String filter) {
55 if (filter == null)
56 throw new IllegalArgumentException("argument 'filter' must not be null");
57 this.filter = filter;
58 filter();
59 }
60
61 /**
62 * clears the current filter
63 *
64 */
65 public void clearFilter() {
66 filter = null;
67 filter();
68 }
69
70 /**
71 * @return the current filter expression; null, if no filter expression is set
72 */
73 public String getFilter() {
74 return filter;
75 }
76
77
78 /**
79 * adds an AutoCompletionListItem to the list. Only adds the item if it
80 * is not null and if not in the list yet.
81 *
82 * @param item the item
83 */
84 public void add(AutoCompletionListItem item) {
85 if (item == null)
86 return;
87 appendOrUpdatePriority(item);
88 sort();
89 filter();
90 }
91
92
93 /**
94 * adds another AutoCompletionList to this list. An item is only
95 * added it is not null and if it does not exist in the list yet.
96 *
97 * @param other another auto completion list; must not be null
98 * @exception IllegalArgumentException thrown, if other is null
99 */
100 public void add(AutoCompletionList other) {
101 if (other == null)
102 throw new IllegalArgumentException("argument 'other' must not be null");
103 for (AutoCompletionListItem item : other.list) {
104 appendOrUpdatePriority(item);
105 }
106 sort();
107 filter();
108 }
109
110
111 /**
112 * adds a list of AutoCompletionListItem to this list. Only items which
113 * are not null and which do not exist yet in the list are added.
114 *
115 * @param other a list of AutoCompletionListItem; must not be null
116 * @exception IllegalArgumentException thrown, if other is null
117 */
118 public void add(List<AutoCompletionListItem> other) {
119 if (other == null)
120 throw new IllegalArgumentException("argument 'other' must not be null");
121 for (AutoCompletionListItem toadd : other) {
122 appendOrUpdatePriority(toadd);
123 }
124 sort();
125 filter();
126 }
127
128 /**
129 * adds a list of strings to this list. Only strings which
130 * are not null and which do not exist yet in the list are added.
131 *
132 * @param value a list of strings to add
133 * @param priority the priority to use
134 */
135 public void add(Collection<String> values, AutoCompletionItemPritority priority) {
136 if (values == null) return;
137 for (String value: values) {
138 if (value == null) {
139 continue;
140 }
141 AutoCompletionListItem item = new AutoCompletionListItem(value,priority);
142 appendOrUpdatePriority(item);
143
144 }
145 sort();
146 filter();
147 }
148
149 protected void appendOrUpdatePriority(AutoCompletionListItem toadd) {
150 AutoCompletionListItem item = lookup(toadd.getValue());
151 if (item == null) {
152 // new item does not exist yet. Add it to the list
153 //
154 list.add(toadd);
155 } else {
156 // new item already exists. Update priority if necessary
157 //
158 if (toadd.getPriority().compareTo(item.getPriority()) < 0) {
159 item.setPriority(toadd.getPriority());
160 }
161 }
162 }
163
164 /**
165 * checks whether a specific item is already in the list. Matches for the
166 * the value <strong>and</strong> the priority of the item
167 *
168 * @param item the item to check
169 * @return true, if item is in the list; false, otherwise
170 */
171 public boolean contains(AutoCompletionListItem item) {
172 if (item == null)
173 return false;
174 return list.contains(item);
175 }
176
177 /**
178 * checks whether an item with the given value is already in the list. Ignores
179 * priority of the items.
180 *
181 * @param value the value of an auto completion item
182 * @return true, if value is in the list; false, otherwise
183 */
184 public boolean contains(String value) {
185 if (value == null)
186 return false;
187 for (AutoCompletionListItem item: list) {
188 if (item.getValue().equals(value))
189 return true;
190 }
191 return false;
192 }
193
194 /**
195 *
196 * @param value a specific value
197 * @return the auto completion item for this value; null, if there is no
198 * such auto completion item
199 */
200 public AutoCompletionListItem lookup(String value) {
201 if (value == null)
202 return null;
203 for (AutoCompletionListItem item : list) {
204 if (item.getValue().equals(value))
205 return item;
206 }
207 return null;
208 }
209
210
211 /**
212 * removes the auto completion item with key <code>key</code>
213 * @param key the key;
214 */
215 public void remove(String key) {
216 if (key == null)
217 return;
218 for (int i=0;i< list.size();i++) {
219 AutoCompletionListItem item = list.get(i);
220 if (item.getValue().equals(key)) {
221 list.remove(i);
222 return;
223 }
224 }
225 }
226
227 /**
228 * sorts the list
229 */
230 protected void sort() {
231 Collections.sort(list);
232 }
233
234 protected void filter() {
235 filtered.clear();
236 if (filter == null) {
237 // Collections.copy throws an exception "Source does not fit in dest"
238 // Collections.copy(filtered, list);
239 filtered.ensureCapacity(list.size());
240 for (AutoCompletionListItem item: list) {
241 filtered.add(item);
242 }
243 return;
244 }
245
246 // apply the pattern to list of possible values. If it matches, add the
247 // value to the list of filtered values
248 //
249 for (AutoCompletionListItem item : list) {
250 if (item.getValue().startsWith(filter)) {
251 filtered.add(item);
252 }
253 }
254 fireTableDataChanged();
255 }
256
257 /**
258 * replies the number of filtered items
259 *
260 * @return the number of filtered items
261 */
262 public int getFilteredSize() {
263 return this.filtered.size();
264 }
265
266 /**
267 * replies the idx-th item from the list of filtered items
268 * @param idx the index; must be in the range 0<= idx < {@see #getFilteredSize()}
269 * @return the item
270 *
271 * @exception IndexOutOfBoundsException thrown, if idx is out of bounds
272 */
273 public AutoCompletionListItem getFilteredItem(int idx) {
274 if (idx < 0 || idx >= getFilteredSize())
275 throw new IndexOutOfBoundsException("idx out of bounds. idx=" + idx);
276 return filtered.get(idx);
277 }
278
279
280 /**
281 * removes all elements from the auto completion list
282 *
283 */
284 public void clear() {
285 list.clear();
286 fireTableDataChanged();
287 }
288
289
290 public int getColumnCount() {
291 return 1;
292 }
293
294 public int getRowCount() {
295
296 return list == null ? 0 : getFilteredSize();
297 }
298
299 public Object getValueAt(int rowIndex, int columnIndex) {
300 return list == null ? null : getFilteredItem(rowIndex);
301 }
302
303}
Note: See TracBrowser for help on using the repository browser.