svn-gvsig-desktop / trunk / libraries / libUI / src / org / gvsig / gui / beans / SearcheableComboBox / JComboBoxSearcheableDynamic.java @ 6459
History | View | Annotate | Download (31.8 KB)
1 |
package org.gvsig.gui.beans.SearcheableComboBox; |
---|---|
2 |
|
3 |
import java.awt.Color; |
4 |
import java.awt.Event; |
5 |
import java.awt.event.KeyEvent; |
6 |
import java.awt.event.KeyListener; |
7 |
import java.util.Arrays; |
8 |
import java.util.HashSet; |
9 |
import java.util.Iterator; |
10 |
import java.util.Set; |
11 |
import java.util.Vector; |
12 |
|
13 |
import javax.swing.ComboBoxEditor; |
14 |
import javax.swing.ComboBoxModel; |
15 |
import javax.swing.DefaultComboBoxModel; |
16 |
import javax.swing.JComboBox; |
17 |
import javax.swing.JOptionPane; |
18 |
import javax.swing.JTextField; |
19 |
|
20 |
import com.iver.andami.PluginServices; |
21 |
|
22 |
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
|
23 |
*
|
24 |
* Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
|
25 |
*
|
26 |
* This program is free software; you can redistribute it and/or
|
27 |
* modify it under the terms of the GNU General Public License
|
28 |
* as published by the Free Software Foundation; either version 2
|
29 |
* of the License, or (at your option) any later version.
|
30 |
*
|
31 |
* This program is distributed in the hope that it will be useful,
|
32 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
33 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
34 |
* GNU General Public License for more details.
|
35 |
*
|
36 |
* You should have received a copy of the GNU General Public License
|
37 |
* along with this program; if not, write to the Free Software
|
38 |
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,USA.
|
39 |
*
|
40 |
* For more information, contact:
|
41 |
*
|
42 |
* Generalitat Valenciana
|
43 |
* Conselleria d'Infraestructures i Transport
|
44 |
* Av. Blasco Ib??ez, 50
|
45 |
* 46010 VALENCIA
|
46 |
* SPAIN
|
47 |
*
|
48 |
* +34 963862235
|
49 |
* gvsig@gva.es
|
50 |
* www.gvsig.gva.es
|
51 |
*
|
52 |
* or
|
53 |
*
|
54 |
* IVER T.I. S.A
|
55 |
* Salamanca 50
|
56 |
* 46005 Valencia
|
57 |
* Spain
|
58 |
*
|
59 |
* +34 963163400
|
60 |
* dac@iver.es
|
61 |
*/
|
62 |
|
63 |
/**
|
64 |
* This class allows users to insert a chain of characters and show all the sentences of the JComboBox that match its first ones characters with it.
|
65 |
* This class is also a Java Bean.
|
66 |
* The behavior of this componet can be configurated by 6 flags:
|
67 |
* + The appearence of the items showed at the beginning and when the user presses the ESCAPE key: (This is configured with 2 flags -> 3 different states are possible)
|
68 |
* -> maintainPositionItems -> When we see the list of all items, this are showed in the ordenation as they have been introduced (if true); (if false) each new item
|
69 |
* when we write on the TextField of this Component will be showed at the end
|
70 |
* -> all_Alphanumeric_Sorted -> All items we can see in this Component will be showed in alphanumeric ordenation (if true)
|
71 |
* + The list of the items showed when the user makes a search writting or pressing the BACK-SPACE key (This is configured with 1 flag -> 2 different states are possible)
|
72 |
* -> alphanumericSortedSearches -> When we write on the TextField of this Component all results (items) are showed in alphanumeric ordenation (if true)
|
73 |
* + Show all items always
|
74 |
* -> showAllItems -> If true -> this component shows all items always; if false -> this component only shows items that their first characters match with the string written by the user
|
75 |
* + Key Sensitive or not when the user writes
|
76 |
* -> key_Sensitive -> When we write on the TextField it can discriminate upper cases from down cases (if true) or not (if false) (This is configured with 1 flag -> 2 different states are possible)
|
77 |
* + Use one color (black) or 2 colors (black by default and red if the string written doesn't match with the beginning of all items)
|
78 |
* -> only_One_Color -> The text on the textField only will be showed on black color (if true); false -> if the text on the textField doesn't match with any current item of this component -> the text
|
79 |
* will be showed on red color
|
80 |
*
|
81 |
* Combinations of flags not allowed:
|
82 |
* -> maintainPositionItems == allAlphanumericSorted == true
|
83 |
* -> ((maintain_Position_Items == false) && (all_Alphanumeric_Sorted == true) && (alphanumeric_Sorted_Searches == false))
|
84 |
* -> showAllItems == true && maintainPositionItems == false
|
85 |
*
|
86 |
* Limitations:
|
87 |
* -> When we add more than one item with the same name (string value) -> the behavior of this component only considers one item in most of the cases when it does a search
|
88 |
* -> If this component has Hundreds,Thousands or even Million/s of items is probably that had quite delay to respond the evens of the user; this also depends of the machine where it's executed
|
89 |
*
|
90 |
* @author Pablo Piqueras Bartolom? (p_queras@hotmail.com)
|
91 |
*/
|
92 |
public class JComboBoxSearcheableDynamic extends JComboBox implements KeyListener, java.io.Serializable { |
93 |
private static final long serialVersionUID = -1853812970336818959L; |
94 |
private Vector defaultItems; |
95 |
private Set notRemovedItems; |
96 |
private Set removedItems; |
97 |
private boolean maintainPositionItems; |
98 |
private boolean alphanumericSortedSearches; |
99 |
private boolean allAlphanumericSorted; |
100 |
private boolean keySensitive; |
101 |
private boolean onlyOneColor; |
102 |
private boolean showAllItems; |
103 |
private boolean allItemsAreSorted; |
104 |
private int lastSelectedItem; |
105 |
private JTextField txtField; |
106 |
|
107 |
/**
|
108 |
* Default Constructor
|
109 |
*/
|
110 |
public JComboBoxSearcheableDynamic() {
|
111 |
// Invokes to the parent class constructor
|
112 |
super();
|
113 |
|
114 |
// Set the default values of the flags
|
115 |
maintainPositionItems = true;
|
116 |
alphanumericSortedSearches = true;
|
117 |
allAlphanumericSorted = false;
|
118 |
keySensitive = false;
|
119 |
onlyOneColor = false;
|
120 |
showAllItems = false;
|
121 |
|
122 |
// Initializates the current Component variables
|
123 |
this.initializateThisComponent();
|
124 |
} |
125 |
|
126 |
/**
|
127 |
* Default Constructor with four parameters: configure the 4 flags
|
128 |
*
|
129 |
* @param boolean (true -> maintains the position of the items; false -> don't maintains the position of the items)
|
130 |
* @param boolean (true -> all items showed when we write on the textfield will be showed in alphanumeric ordenation; false -> they don't have to be in alphanumeric ordenation)
|
131 |
* @param boolean (true -> all items showed will be in alphanumeric ordenation; false -> they don't have to be in alphanumeric ordenation)
|
132 |
* @param boolean (true -> discriminates capital letters from small letters; false -> don't discriminates capital letters from small letters)
|
133 |
*/
|
134 |
public JComboBoxSearcheableDynamic(boolean maintain_Position_Items, boolean alphanumeric_Sorted_Searches, boolean all_Alphanumeric_Sorted, boolean key_Sensitive) { |
135 |
// Invokes to the parent class constructor
|
136 |
super();
|
137 |
|
138 |
// Sets the options selected by the user
|
139 |
maintainPositionItems = maintain_Position_Items; |
140 |
allAlphanumericSorted = all_Alphanumeric_Sorted; |
141 |
alphanumericSortedSearches = alphanumeric_Sorted_Searches | allAlphanumericSorted; // If allAlphanumericSorted = true -> alphanumericSortedSearches = true
|
142 |
keySensitive = key_Sensitive; |
143 |
onlyOneColor = false;
|
144 |
showAllItems = false;
|
145 |
|
146 |
if (!testFlagsConfigurationOK())
|
147 |
JOptionPane.showMessageDialog(this, PluginServices.getText(this, "error_message_JComboBoxSearcheableDynamic"), PluginServices.getText(this, "exportJOP2Title"), JOptionPane.ERROR_MESSAGE); |
148 |
else
|
149 |
this.initializateThisComponent(); // Initializates the current Component variables |
150 |
} |
151 |
|
152 |
/**
|
153 |
* Default Constructor with four parameters: configure the 6 flags
|
154 |
*
|
155 |
* @param boolean (true -> maintains the position of the items; false -> don't maintains the position of the items)
|
156 |
* @param boolean (true -> all items showed when we write on the textfield will be showed in alphanumeric ordenation; false -> they don't have to be in alphanumeric ordenation)
|
157 |
* @param boolean (true -> all items showed will be in alphanumeric ordenation; false -> they don't have to be in alphanumeric ordenation)
|
158 |
* @param boolean (true -> discriminates capital letters from small letters; false -> don't discriminates capital letters from small letters)
|
159 |
* @param boolean (true -> the text on the textField only will be showed on black color (if true); false -> if the text on the textField doesn't match with any current item of this component -> the text
|
160 |
* will be showed on red color)
|
161 |
* @param boolean (true -> this component shows all items always; false -> this component only shows items that their first characters match with the string written by the user)
|
162 |
*/
|
163 |
public JComboBoxSearcheableDynamic(boolean maintain_Position_Items, boolean alphanumeric_Sorted_Searches, boolean all_Alphanumeric_Sorted, boolean key_Sensitive, boolean only_One_Color, boolean show_All_Items) { |
164 |
// Invokes to the parent class constructor
|
165 |
super();
|
166 |
|
167 |
// Sets the options selected by the user
|
168 |
maintainPositionItems = maintain_Position_Items; |
169 |
allAlphanumericSorted = all_Alphanumeric_Sorted; |
170 |
alphanumericSortedSearches = alphanumeric_Sorted_Searches | allAlphanumericSorted; // If allAlphanumericSorted = true -> alphanumericSortedSearches = true
|
171 |
keySensitive = key_Sensitive; |
172 |
onlyOneColor = only_One_Color; |
173 |
showAllItems = show_All_Items; |
174 |
|
175 |
if (!testFlagsConfigurationOK())
|
176 |
JOptionPane.showMessageDialog(this, PluginServices.getText(this, "error_message_JComboBoxSearcheableDynamic"), PluginServices.getText(this, "exportJOP2Title"), JOptionPane.ERROR_MESSAGE); |
177 |
else
|
178 |
this.initializateThisComponent(); // Initializates the current Component variables |
179 |
} |
180 |
|
181 |
/**
|
182 |
* Starts all the variables needed for this Component
|
183 |
*/
|
184 |
private void initializateThisComponent() { |
185 |
try
|
186 |
{ |
187 |
// Allows user to edit on the combobox
|
188 |
setEditable(true);
|
189 |
|
190 |
// Gets the editor of the combobox_fwAndami
|
191 |
ComboBoxEditor editor = this.getEditor(); |
192 |
|
193 |
// Gets JTextField of the editor of the combobox
|
194 |
JTextField textField = (JTextField) editor.getEditorComponent(); |
195 |
|
196 |
// Adds a KeyListener to the JTextField of the editor of the combobox
|
197 |
textField.addKeyListener(this);
|
198 |
|
199 |
// Disable the focus transversal keys (Example: CTRL+TAB) for enable the TAB key
|
200 |
textField.setFocusTraversalKeysEnabled(false);
|
201 |
|
202 |
// Initialize the Vector with the items
|
203 |
defaultItems = new Vector(); |
204 |
|
205 |
// If we don't have to show all items each time
|
206 |
if (!showAllItems)
|
207 |
{ |
208 |
// Initialize the Set for store the items removed from the JComboBox
|
209 |
removedItems = new HashSet(); |
210 |
|
211 |
// Initialize the Set for store the items won't be removed from the JComboBox
|
212 |
if (alphanumericSortedSearches)
|
213 |
notRemovedItems = new HashSet(); |
214 |
} |
215 |
|
216 |
// By default all items showed aren't sorted
|
217 |
allItemsAreSorted = false;
|
218 |
|
219 |
// Set the last selected item
|
220 |
lastSelectedItem = 0;
|
221 |
} |
222 |
catch(Exception e) |
223 |
{ |
224 |
e.printStackTrace(); |
225 |
} |
226 |
} |
227 |
|
228 |
/**
|
229 |
* This method tests the configuration of the flags and returns true or false if its ok or not with the
|
230 |
* logical behavior of this component
|
231 |
*
|
232 |
* @return boolean True if the configuration of the flags is oks, false if not
|
233 |
*/
|
234 |
public boolean testFlagsConfigurationOK() { |
235 |
if ((maintainPositionItems == allAlphanumericSorted) && (maintainPositionItems == true)) |
236 |
return false; |
237 |
|
238 |
if ((maintainPositionItems == false) && (allAlphanumericSorted == true) && (alphanumericSortedSearches == false)) |
239 |
return false; |
240 |
|
241 |
if ((showAllItems == true) && (maintainPositionItems == false)) |
242 |
return false; |
243 |
|
244 |
return true; |
245 |
} |
246 |
|
247 |
|
248 |
/**
|
249 |
* Redefines the method addItem of the JComboBox
|
250 |
*
|
251 |
* @param Object the item to add
|
252 |
*/
|
253 |
public void addItem(Object anObject) { |
254 |
// Add the item to this component
|
255 |
super.addItem(anObject);
|
256 |
|
257 |
// In defaultItems it's saved a copy ordered of the items
|
258 |
defaultItems.add(anObject); |
259 |
|
260 |
// If we don't have to show all items each time
|
261 |
if (!showAllItems)
|
262 |
{ |
263 |
// Store a copy of each item that is in this component
|
264 |
if (alphanumericSortedSearches)
|
265 |
notRemovedItems.add(anObject); |
266 |
} |
267 |
else
|
268 |
{ |
269 |
if ((allAlphanumericSorted) && (!allItemsAreSorted))
|
270 |
{ |
271 |
this.setModel(this.sortItemsShowed()); |
272 |
allItemsAreSorted = true;
|
273 |
} |
274 |
} |
275 |
} |
276 |
|
277 |
/**
|
278 |
* This private method makes a copy of items sorted and returns the copy
|
279 |
*
|
280 |
* @return ComboBoxModel The ComboBoxModel with the copy of the items
|
281 |
*/
|
282 |
private ComboBoxModel getCopyOfItems() { |
283 |
|
284 |
DefaultComboBoxModel dCBModel = new DefaultComboBoxModel(); |
285 |
int i;
|
286 |
|
287 |
Object sorted[] = notRemovedItems.toArray(); |
288 |
Arrays.sort(sorted);
|
289 |
|
290 |
// For each item -> makes a copy if hasn't removed
|
291 |
for (i=0; i < sorted.length; i++) |
292 |
dCBModel.addElement(sorted[i]); |
293 |
|
294 |
return dCBModel;
|
295 |
} |
296 |
|
297 |
/**
|
298 |
* This private method makes a copy of items according to the configuration, this method is invoked when the uses releases the key ESC(APE)
|
299 |
*
|
300 |
* @return ComboBoxModel The ComboBoxModel with the copy of the items
|
301 |
*/
|
302 |
private ComboBoxModel getCopyOfModel() { |
303 |
|
304 |
if (maintainPositionItems) // Copies the default items in the same ordenation |
305 |
{ |
306 |
DefaultComboBoxModel dCBModel = new DefaultComboBoxModel(); |
307 |
int i;
|
308 |
|
309 |
// For each item -> makes a copy
|
310 |
for (i=0; i < defaultItems.size(); i++) |
311 |
dCBModel.addElement(defaultItems.get(i)); |
312 |
|
313 |
return dCBModel;
|
314 |
} |
315 |
else
|
316 |
{ |
317 |
// Get a copy of the items sorted
|
318 |
if ((allAlphanumericSorted) || (alphanumericSortedSearches))
|
319 |
{ |
320 |
DefaultComboBoxModel dCBModel = new DefaultComboBoxModel(); |
321 |
int i;
|
322 |
|
323 |
Object sorted[] = defaultItems.toArray(); |
324 |
Arrays.sort(sorted);
|
325 |
|
326 |
// For each item -> makes a copy
|
327 |
for (i=0; i < sorted.length; i++) |
328 |
dCBModel.addElement(sorted[i]); |
329 |
|
330 |
return dCBModel;
|
331 |
} |
332 |
else
|
333 |
{ |
334 |
// This option isn't used
|
335 |
return new DefaultComboBoxModel(); |
336 |
} |
337 |
} |
338 |
} |
339 |
|
340 |
/**
|
341 |
* This private method makes a copy of items according to the configuration, this method is invoked when the uses releases the key BACK_SPACE or any key of alphanumeric or simbol character
|
342 |
*
|
343 |
* @return ComboBoxModel The ComboBoxModel with the copy of the items
|
344 |
*/
|
345 |
private ComboBoxModel getCopyOfModelSearched() { |
346 |
|
347 |
if (alphanumericSortedSearches) // Copies the items sorted |
348 |
return getCopyOfItems();
|
349 |
else
|
350 |
return this.getModel(); |
351 |
} |
352 |
|
353 |
/**
|
354 |
* This private method sorts the items of the vector of the model of this component
|
355 |
*
|
356 |
* @return ComboBoxModel The ComboBoxModel with the items sorted by alphanumeric order
|
357 |
*/
|
358 |
private ComboBoxModel sortItemsShowed() { |
359 |
DefaultComboBoxModel dCBModel = new DefaultComboBoxModel(); |
360 |
int i;
|
361 |
|
362 |
Object sorted[] = defaultItems.toArray(); |
363 |
Arrays.sort(sorted);
|
364 |
|
365 |
// For each item -> makes a copy if hasn't removed
|
366 |
for (i=0; i < sorted.length; i++) |
367 |
dCBModel.addElement(sorted[i]); |
368 |
|
369 |
return dCBModel;
|
370 |
} |
371 |
|
372 |
/**
|
373 |
* This private method finds the first item of the vector of the model of this component that it start matches with a chain of characters
|
374 |
*
|
375 |
* @param String text
|
376 |
* @return int The position of the first coincidence or -1 if hasn't find any coincidence
|
377 |
*/
|
378 |
private int findFirstCoincidence(String text) { |
379 |
int first_position = 0; |
380 |
boolean matchesTheStart = false; |
381 |
|
382 |
// If there is key sensitive
|
383 |
if (keySensitive)
|
384 |
{ |
385 |
// Find the first match
|
386 |
while ((first_position < this.getItemCount()) && (matchesTheStart == false)) |
387 |
{ |
388 |
if (((String)this.getItemAt(first_position)).startsWith(text)) |
389 |
matchesTheStart = true;
|
390 |
else
|
391 |
first_position++; // Increments index
|
392 |
} |
393 |
} |
394 |
else
|
395 |
{ |
396 |
// If there isn't key sensitive
|
397 |
|
398 |
// Find the first match
|
399 |
while ((first_position < this.getItemCount()) && (matchesTheStart == false)) |
400 |
{ |
401 |
if (((this.getItemAt(first_position)).toString().toUpperCase()).startsWith(text.toUpperCase())) |
402 |
matchesTheStart = true;
|
403 |
else
|
404 |
first_position++; // Increments index
|
405 |
} |
406 |
} |
407 |
|
408 |
// Return the position value
|
409 |
if (!matchesTheStart)
|
410 |
return -1; |
411 |
else
|
412 |
return first_position;
|
413 |
} |
414 |
|
415 |
/**
|
416 |
* Gets the flag of the configuration of the policy for maintain the position of the items of this component
|
417 |
* (true -> maintains the position of the items, false -> don't maintains the position of the items)
|
418 |
*
|
419 |
* @return boolean The value of the flag
|
420 |
*/
|
421 |
public boolean isMaintainPositionItems() { |
422 |
return maintainPositionItems;
|
423 |
} |
424 |
|
425 |
/**
|
426 |
* Sets the flag of the configuration of the policy for maintain the position of the items of this component
|
427 |
* (true -> maintains the position of the items, false -> don't maintains the position of the items)
|
428 |
*
|
429 |
* @param boolean The value of the flag
|
430 |
*/
|
431 |
public void setMaintainPositionItems(boolean maintain_Position_Items) { |
432 |
this.maintainPositionItems = maintain_Position_Items;
|
433 |
|
434 |
if (!this.testFlagsConfigurationOK()) |
435 |
JOptionPane.showMessageDialog(this, PluginServices.getText(this, "error_message_JComboBoxSearcheableDynamic"), PluginServices.getText(this, "exportJOP2Title"), JOptionPane.ERROR_MESSAGE); |
436 |
} |
437 |
|
438 |
/**
|
439 |
* Gets the flag of the configuration of the alphanumericSortedSearches flag of this component
|
440 |
* (true -> all items showed when we write on the textfield will be showed in alphanumeric ordenation; false -> they don't have to be in alphanumeric ordenation)
|
441 |
*
|
442 |
* @return boolean The value of the flag
|
443 |
*/
|
444 |
public boolean isAlphanumericSortedSearches() { |
445 |
return alphanumericSortedSearches;
|
446 |
} |
447 |
|
448 |
/**
|
449 |
* Sets the flag of the configuration of the alphanumericSortedSearches flag of this component
|
450 |
* (true -> all items showed when we write on the textfield will be showed in alphanumeric ordenation; false -> they don't have to be in alphanumeric ordenation)
|
451 |
*
|
452 |
* @param boolean The value of the flag
|
453 |
*/
|
454 |
public void setAlphanumericSortedSearches(boolean alphanumeric_Sorted_Searches) { |
455 |
this.alphanumericSortedSearches = alphanumeric_Sorted_Searches;
|
456 |
|
457 |
if (!testFlagsConfigurationOK())
|
458 |
JOptionPane.showMessageDialog(this, PluginServices.getText(this, "error_message_JComboBoxSearcheableDynamic"), PluginServices.getText(this, "exportJOP2Title"), JOptionPane.ERROR_MESSAGE); |
459 |
|
460 |
if (alphanumericSortedSearches)
|
461 |
{ |
462 |
notRemovedItems = new HashSet(); |
463 |
|
464 |
for (int i=0; i < this.getItemCount(); i++) |
465 |
notRemovedItems.add(this.getItemAt(i));
|
466 |
} |
467 |
else
|
468 |
notRemovedItems.clear(); |
469 |
|
470 |
} |
471 |
|
472 |
/**
|
473 |
* Gets the flag of the configuration of the allAlphanumericSorted flag of this component
|
474 |
* (true -> all items showed will be in alphanumeric ordenation; false -> they don't have to be in alphanumeric ordenation)
|
475 |
*
|
476 |
* @return boolean The value of the flag
|
477 |
*/
|
478 |
public boolean isAllAlphanumericSorted() { |
479 |
return allAlphanumericSorted;
|
480 |
} |
481 |
|
482 |
/**
|
483 |
* Sets the flag of the configuration of the allAlphanumericSorted flag of this component
|
484 |
* (true -> all items showed will be in alphanumeric ordenation; false -> they don't have to be in alphanumeric ordenation)
|
485 |
*
|
486 |
* @param boolean The value of the flag
|
487 |
*/
|
488 |
public void setAllAlphanumericSorted(boolean all_Alphanumeric_Sorted) { |
489 |
this.allAlphanumericSorted = all_Alphanumeric_Sorted;
|
490 |
|
491 |
// If all_Alphanumeric_Sorted = true -> alphanumeric_Sorted_Searches = true
|
492 |
setAlphanumericSortedSearches(this.alphanumericSortedSearches | this.allAlphanumericSorted); |
493 |
|
494 |
if (allAlphanumericSorted)
|
495 |
|
496 |
if (!testFlagsConfigurationOK())
|
497 |
JOptionPane.showMessageDialog(this, PluginServices.getText(this, "error_message_JComboBoxSearcheableDynamic"), PluginServices.getText(this, "exportJOP2Title"), JOptionPane.ERROR_MESSAGE); |
498 |
} |
499 |
|
500 |
/**
|
501 |
* Gets the flag of the configuration of the keySensitive flag of this component
|
502 |
* (true -> discriminates capital letters from small letters ,false -> don't discriminates capital letters from small letters)
|
503 |
*
|
504 |
* @return boolean The value of the flag
|
505 |
*/
|
506 |
public boolean isKeySensitive() { |
507 |
return keySensitive;
|
508 |
} |
509 |
|
510 |
/**
|
511 |
* Sets the flag of the configuration of the keySensitive flag of this component
|
512 |
* (true -> discriminates capital letters from small letters ,false -> don't discriminates capital letters from small letters)
|
513 |
*
|
514 |
* @param boolean The value of the flag
|
515 |
*/
|
516 |
public void setKeySensitive(boolean key_Sensitive) { |
517 |
this.keySensitive = key_Sensitive;
|
518 |
|
519 |
if (!testFlagsConfigurationOK())
|
520 |
JOptionPane.showMessageDialog(this, PluginServices.getText(this, "error_message_JComboBoxSearcheableDynamic"), PluginServices.getText(this, "exportJOP2Title"), JOptionPane.ERROR_MESSAGE); |
521 |
} |
522 |
|
523 |
/**
|
524 |
* Gets the flag of the configuration of the onlyOneColor flag of this component
|
525 |
* (true -> The text on the textField only will be showed on black color; false -> if the text on the textField doesn't match with any current item of this
|
526 |
* component -> the text will be showed on red color)
|
527 |
*
|
528 |
* @return boolean The value of the flag
|
529 |
*/
|
530 |
public boolean isOnlyOneColor() { |
531 |
return onlyOneColor;
|
532 |
} |
533 |
|
534 |
|
535 |
/**
|
536 |
* Sets the flag of the configuration of the onlyOneColor flag of this component
|
537 |
* (true -> discriminates capital letters from small letters ,false -> don't discriminates capital letters from small letters)
|
538 |
*
|
539 |
* @param boolean The value of the flag
|
540 |
*/
|
541 |
public void setOnlyOneColor(boolean only_One_Color) { |
542 |
this.onlyOneColor = only_One_Color;
|
543 |
|
544 |
if (!testFlagsConfigurationOK())
|
545 |
JOptionPane.showMessageDialog(this, PluginServices.getText(this, "error_message_JComboBoxSearcheableDynamic"), PluginServices.getText(this, "exportJOP2Title"), JOptionPane.ERROR_MESSAGE); |
546 |
} |
547 |
|
548 |
/**
|
549 |
* Gets the flag of the configuration of the showAllItems flag of this component
|
550 |
* (true -> this component shows all items always; false -> this component only shows items that their first characters match with the string written by the user)
|
551 |
*
|
552 |
* @return boolean The value of the flag
|
553 |
*/
|
554 |
public boolean isShowAllItems() { |
555 |
return showAllItems;
|
556 |
} |
557 |
|
558 |
/**
|
559 |
* Sets the flag of the configuration of the showAllItems flag of this component
|
560 |
* (true -> this component shows all items always; false -> this component only shows items that their first characters match with the string written by the user)
|
561 |
*
|
562 |
* @return boolean The value of the flag
|
563 |
*/
|
564 |
public void setShowAllItems(boolean show_All_Items) { |
565 |
this.showAllItems = show_All_Items;
|
566 |
|
567 |
if (this.showAllItems == false) |
568 |
this.setModel(getCopyOfModel());
|
569 |
} |
570 |
|
571 |
|
572 |
//// IMPLEMENTATION OF THE METHODS OF THE KEYLISTENER ////
|
573 |
|
574 |
/*
|
575 |
* (non-Javadoc)
|
576 |
*
|
577 |
* @see java.awt.event.KeyListener#keyTyped(java.awt.event.KeyEvent)
|
578 |
*/
|
579 |
public void keyTyped(KeyEvent ke) { |
580 |
} |
581 |
|
582 |
/*
|
583 |
* (non-Javadoc)
|
584 |
*
|
585 |
* @see java.awt.event.KeyListener#keyPressed(java.awt.event.KeyEvent)
|
586 |
*/
|
587 |
public void keyPressed(KeyEvent ke) { |
588 |
} |
589 |
|
590 |
/*
|
591 |
* (non-Javadoc)
|
592 |
*
|
593 |
* @see java.awt.event.KeyListener#keyReleased(java.awt.event.KeyEvent)
|
594 |
*/
|
595 |
public void keyReleased(KeyEvent ke) { |
596 |
|
597 |
// Get the JTextField of the Editor of the JComboBox (where the user has written)
|
598 |
// JTextField txtField = (JTextField) ke.getSource();
|
599 |
txtField = (JTextField) ke.getSource();
|
600 |
|
601 |
if (ke.getKeyCode() == KeyEvent.VK_DOWN) { |
602 |
// If the key (typed, pressed and) released has been the Down Key -> when there isn't any text (item of the list) selected, select the first
|
603 |
ComboBoxModel model = this.getModel(); |
604 |
if ((this.getItemCount() > 0) && (lastSelectedItem == (this.getItemCount()-1))) { |
605 |
this.setSelectedIndex(0); |
606 |
} |
607 |
|
608 |
lastSelectedItem = this.getSelectedIndex();
|
609 |
this.showPopup();
|
610 |
} else if (ke.getKeyCode() == KeyEvent.VK_UP) { |
611 |
// If the key (typed, pressed and) released has been the Up Key -> when there isn't any text (item of the list) selected, select the last
|
612 |
ComboBoxModel model = this.getModel(); |
613 |
|
614 |
if (lastSelectedItem == 0) { |
615 |
this.setSelectedIndex(this.getItemCount()-1); |
616 |
} |
617 |
|
618 |
lastSelectedItem = this.getSelectedIndex();
|
619 |
this.showPopup();
|
620 |
} else if (ke.getKeyChar() == KeyEvent.VK_ESCAPE) { |
621 |
// If the key (typed, pressed and) released has been the Escape Key -> hide the popup list and empty the JTextField
|
622 |
this.hidePopup();
|
623 |
|
624 |
if ((!maintainPositionItems) && (!allAlphanumericSorted))
|
625 |
{ |
626 |
if (removedItems.size() > 0) |
627 |
{ |
628 |
Iterator it = removedItems.iterator();
|
629 |
|
630 |
while(it.hasNext())
|
631 |
super.addItem(it.next());
|
632 |
|
633 |
removedItems.clear(); |
634 |
} |
635 |
} |
636 |
else
|
637 |
this.setModel(getCopyOfModel());
|
638 |
|
639 |
txtField.setText("");
|
640 |
this.setSelectedIndex(-1); |
641 |
} else if (ke.getKeyChar() == KeyEvent.VK_ENTER) { |
642 |
// If the key (typed, pressed and) released has been the Enter Key -> hide the popup list and select the characters introduced
|
643 |
|
644 |
ComboBoxModel model = this.getModel(); |
645 |
|
646 |
if (getSelectedItem() != null) { |
647 |
txtField.setText(getSelectedItem().toString()); |
648 |
|
649 |
// Find if the string matches with any item -> if not -> change the foreground color to RED
|
650 |
if (!onlyOneColor)
|
651 |
{ |
652 |
for (int i=0; i < this.getItemCount(); i++) |
653 |
{ |
654 |
if (((String)this.getModel().getElementAt(i)).compareTo(txtField.getText()) == 0) |
655 |
{ |
656 |
txtField.setForeground(Color.BLACK);
|
657 |
return;
|
658 |
} |
659 |
} |
660 |
txtField.setForeground(Color.RED);
|
661 |
} |
662 |
|
663 |
model.setSelectedItem(getSelectedItem()); |
664 |
} |
665 |
} else if (ke.getKeyChar() == Event.BACK_SPACE) { |
666 |
// If the key (typed, pressed and) released has been the TAB Key -> try to complete the current selected item from the list and hide the popup list
|
667 |
|
668 |
int i = 0; |
669 |
String s;
|
670 |
String text = txtField.getText();
|
671 |
boolean matchesTheStart = false; |
672 |
|
673 |
// If it has to maintain the position of the items
|
674 |
if (showAllItems)
|
675 |
{ |
676 |
int first_match = this.findFirstCoincidence(text); |
677 |
|
678 |
// If has find a coincidence -> marks the item, else -> reset the index
|
679 |
this.setSelectedIndex(first_match);
|
680 |
|
681 |
txtField.setText(text); |
682 |
txtField.setForeground(Color.BLACK);
|
683 |
this.showPopup();
|
684 |
|
685 |
} |
686 |
else
|
687 |
{ |
688 |
Object objs[] = removedItems.toArray(); |
689 |
|
690 |
if (alphanumericSortedSearches)
|
691 |
{ |
692 |
if (keySensitive)
|
693 |
{ |
694 |
// If there is key sensitive
|
695 |
while (i < objs.length)
|
696 |
{ |
697 |
s = objs[i].toString(); |
698 |
if (s.startsWith(text))
|
699 |
{ |
700 |
removedItems.remove(objs[i]); |
701 |
notRemovedItems.add(objs[i]); |
702 |
matchesTheStart = true;
|
703 |
} |
704 |
|
705 |
// Increments index
|
706 |
i++; |
707 |
} |
708 |
} |
709 |
else
|
710 |
{ |
711 |
// If there isn't key sensitive
|
712 |
while (i < objs.length)
|
713 |
{ |
714 |
s = (objs[i].toString().toUpperCase()); |
715 |
if (s.startsWith(text.toUpperCase()))
|
716 |
{ |
717 |
removedItems.remove(objs[i]); |
718 |
notRemovedItems.add(objs[i]); |
719 |
matchesTheStart = true;
|
720 |
} |
721 |
|
722 |
// Increments index
|
723 |
i++; |
724 |
} |
725 |
} |
726 |
|
727 |
this.setModel(getCopyOfModelSearched());
|
728 |
|
729 |
if (notRemovedItems.contains(text))
|
730 |
txtField.setForeground(Color.BLACK);
|
731 |
} |
732 |
else
|
733 |
{ |
734 |
this.hidePopup();
|
735 |
|
736 |
// If it hasn't to maintain the position of the items
|
737 |
if (keySensitive)
|
738 |
{ |
739 |
// If there is key sensitive
|
740 |
while (i < objs.length)
|
741 |
{ |
742 |
s = objs[i].toString(); |
743 |
if (s.startsWith(text))
|
744 |
{ |
745 |
removedItems.remove(objs[i]); |
746 |
super.addItem(objs[i]);
|
747 |
matchesTheStart = true;
|
748 |
} |
749 |
|
750 |
// Increments index
|
751 |
i++; |
752 |
} |
753 |
} |
754 |
else
|
755 |
{ |
756 |
// If there isn't key sensitive
|
757 |
while (i < objs.length)
|
758 |
{ |
759 |
s = ((String)objs[i].toString().toUpperCase());
|
760 |
|
761 |
if (s.startsWith(text.toUpperCase()))
|
762 |
{ |
763 |
removedItems.remove(objs[i]); |
764 |
super.addItem(objs[i]);
|
765 |
matchesTheStart = true;
|
766 |
} |
767 |
|
768 |
// Increments index
|
769 |
i++; |
770 |
} |
771 |
} |
772 |
} |
773 |
} |
774 |
|
775 |
txtField.setText(text); |
776 |
|
777 |
if (matchesTheStart)
|
778 |
txtField.setForeground(Color.BLACK);
|
779 |
|
780 |
this.showPopup();
|
781 |
} else if (ke.getKeyCode() == KeyEvent.VK_TAB) { |
782 |
// If the key (typed, pressed and) released has been the TAB Key -> try to complete the current selected item from the list and hide the popup list
|
783 |
ComboBoxModel model = this.getModel(); |
784 |
if (model.getSelectedItem() == null) |
785 |
{ |
786 |
// If there isn't any item selected and there are items, select and show the first item
|
787 |
if (model.getSize() > 0) |
788 |
{ |
789 |
this.setSelectedIndex(0); |
790 |
txtField.setText(model.getSelectedItem().toString()); |
791 |
} |
792 |
else
|
793 |
txtField.setText(""); // If there isn't any item selected and there aren't items, show anything |
794 |
} |
795 |
else
|
796 |
txtField.setText(model.getSelectedItem().toString()); |
797 |
this.hidePopup();
|
798 |
} else if (ke.getKeyCode() == KeyEvent.VK_LEFT) { |
799 |
// Do nothing
|
800 |
} else if (ke.getKeyCode() == KeyEvent.VK_RIGHT) { |
801 |
// Do nothing
|
802 |
} else if (txtField.getText().trim().equalsIgnoreCase("")) { |
803 |
// If the current string in the JTextField of the Editor is an empty string -> hide the popup list and the reset the index
|
804 |
this.setSelectedIndex(-1); |
805 |
this.hidePopup();
|
806 |
} else {
|
807 |
// When the user writtes a new character -> find a item of the list that matches it start with the characters written
|
808 |
// If matches the text -> change the color of the text to black, else -> change the color of the text to red and doesn't select any item from the list
|
809 |
|
810 |
ComboBoxModel model = this.getModel(); |
811 |
String text = txtField.getText();
|
812 |
|
813 |
// Try to match the characters written with the start of any string value of item of the list
|
814 |
int i = 0; |
815 |
String s;
|
816 |
boolean matchesTheStart = false; |
817 |
|
818 |
// If it has to maintain the position of the items
|
819 |
if (showAllItems)
|
820 |
{ |
821 |
txtField.setText(text); |
822 |
|
823 |
int first_match = this.findFirstCoincidence(text); |
824 |
|
825 |
// If has find a coincidence -> marks the item, else -> reset the index
|
826 |
this.setSelectedIndex(first_match);
|
827 |
|
828 |
// Sets the written text to the text field
|
829 |
txtField.setText(text); |
830 |
|
831 |
// If has matched the text written with any item -> set the text on black color
|
832 |
// else -> set the text on red color
|
833 |
if (!onlyOneColor)
|
834 |
{ |
835 |
if (first_match > -1) |
836 |
txtField.setForeground(Color.BLACK);
|
837 |
else
|
838 |
txtField.setForeground(Color.RED);
|
839 |
} |
840 |
|
841 |
this.showPopup();
|
842 |
return;
|
843 |
} |
844 |
else
|
845 |
{ |
846 |
if (alphanumericSortedSearches)
|
847 |
{ |
848 |
if (keySensitive)
|
849 |
{ |
850 |
while (i < model.getSize())
|
851 |
{ |
852 |
s = model.getElementAt(i).toString(); |
853 |
|
854 |
// If matches the start
|
855 |
if (s.startsWith(text)) {
|
856 |
matchesTheStart = true;
|
857 |
|
858 |
// Increments index
|
859 |
i++; |
860 |
} |
861 |
else
|
862 |
{ |
863 |
// When the characters written doesn't match -> set this characters to red color
|
864 |
removedItems.add(model.getElementAt(i)); |
865 |
notRemovedItems.remove(model.getElementAt(i)); |
866 |
this.removeItemAt(i);
|
867 |
} |
868 |
} |
869 |
} |
870 |
else
|
871 |
{ |
872 |
while (i < model.getSize())
|
873 |
{ |
874 |
s = (model.getElementAt(i).toString().toUpperCase()); |
875 |
|
876 |
// If matches the start
|
877 |
if (s.startsWith(text.toUpperCase())) {
|
878 |
matchesTheStart = true;
|
879 |
|
880 |
// Increments index
|
881 |
i++; |
882 |
} |
883 |
else
|
884 |
{ |
885 |
// When the characters written doesn't match -> set this characters to red color
|
886 |
removedItems.add(model.getElementAt(i)); |
887 |
notRemovedItems.remove(model.getElementAt(i)); |
888 |
this.removeItemAt(i);
|
889 |
} |
890 |
} |
891 |
} |
892 |
|
893 |
this.setModel(getCopyOfModelSearched());
|
894 |
} |
895 |
else
|
896 |
{ |
897 |
this.hidePopup();
|
898 |
|
899 |
if (keySensitive)
|
900 |
{ |
901 |
while (i < model.getSize())
|
902 |
{ |
903 |
s = model.getElementAt(i).toString(); |
904 |
|
905 |
// If matches the start
|
906 |
if (s.startsWith(text)) {
|
907 |
matchesTheStart = true;
|
908 |
|
909 |
// Increments index
|
910 |
i++; |
911 |
} |
912 |
else
|
913 |
{ |
914 |
// When the characters written doesn't match -> set this characters to red color
|
915 |
removedItems.add(model.getElementAt(i)); |
916 |
this.removeItemAt(i);
|
917 |
} |
918 |
} |
919 |
} |
920 |
else
|
921 |
{ |
922 |
while (i < model.getSize())
|
923 |
{ |
924 |
s = (model.getElementAt(i).toString().toUpperCase()); |
925 |
|
926 |
// If matches the start
|
927 |
if (s.startsWith(text.toUpperCase())) {
|
928 |
matchesTheStart = true;
|
929 |
|
930 |
// Increments index
|
931 |
i++; |
932 |
} |
933 |
else
|
934 |
{ |
935 |
// When the characters written doesn't match -> set this characters to red color
|
936 |
removedItems.add(model.getElementAt(i)); |
937 |
this.removeItemAt(i);
|
938 |
} |
939 |
} |
940 |
} |
941 |
} |
942 |
} |
943 |
|
944 |
// Reset the index
|
945 |
if (this.getItemCount() > 0) |
946 |
this.setSelectedIndex(0); |
947 |
else
|
948 |
this.setSelectedIndex(-1); |
949 |
|
950 |
// Sets the written text to the text field
|
951 |
txtField.setText(text); |
952 |
|
953 |
// If has matched the text written with any item -> set the text on black color
|
954 |
// else -> set the text on red color
|
955 |
if (!onlyOneColor)
|
956 |
{ |
957 |
if (matchesTheStart)
|
958 |
txtField.setForeground(Color.BLACK);
|
959 |
else
|
960 |
txtField.setForeground(Color.RED);
|
961 |
} |
962 |
|
963 |
this.showPopup();
|
964 |
} |
965 |
} |
966 |
} |