Statistics
| Revision:

root / trunk / libraries / libUI / src / org / gvsig / gui / beans / SearcheableComboBox / JComboBoxSearcheableDynamic.java @ 6503

History | View | Annotate | Download (33.2 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
*  + Key Sensitive or not when the user writes 
74
*      -> 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)
75
*  + 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)
76
*      -> 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
77
*            will be showed on red color
78
*  + Show all items always
79
*      -> 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
80
* 
81
* Default Values of the Flags:
82
*  -> maintainPositionItems -> true
83
*  -> all_Alphanumeric_Sorted -> true
84
*  -> alphanumericSortedSearches -> false 
85
*  -> key_Sensitive -> false
86
*  -> only_One_Color -> false
87
*  -> showAllItems -> false
88
* 
89
* Combinations of flags not allowed:
90
*         ->        maintainPositionItems == allAlphanumericSorted == true
91
*        ->        ((maintain_Position_Items == false) && (all_Alphanumeric_Sorted == true) && (alphanumeric_Sorted_Searches == false))
92
*   ->  showAllItems == true && maintainPositionItems == false
93
* 
94
* Limitations:
95
* -> 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
96
* -> 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
97
* 
98
* @author Pablo Piqueras Bartolom? (p_queras@hotmail.com)
99
*/
100
public class JComboBoxSearcheableDynamic extends JComboBox implements KeyListener, java.io.Serializable {
101
        private static final long serialVersionUID = -1853812970336818959L;
102
        private Vector defaultItems;
103
        private Set notRemovedItems;
104
        private Set removedItems;
105
        // FLAGS
106
        private boolean maintainPositionItems;        
107
        private boolean alphanumericSortedSearches;
108
        private boolean allAlphanumericSorted;
109
        private boolean keySensitive;
110
        private boolean onlyOneColor;
111
        private boolean showAllItems;
112
        // END FLAGS
113
        private boolean allItemsAreSorted;
114
        private int lastSelectedItem;
115
        private JTextField txtField;
116
        
117
        /**
118
         * Default Constructor
119
         */
120
        public JComboBoxSearcheableDynamic() {
121
                // Invokes to the parent class constructor                
122
                super();
123
        
124
                // Set the default values of the flags
125
                maintainPositionItems = true;                
126
                alphanumericSortedSearches = true;
127
                allAlphanumericSorted = false;
128
                keySensitive = false;
129
                onlyOneColor = false;
130
                showAllItems = false;
131
                
132
                // Initializates the current Component variables
133
                this.initializateThisComponent();
134
        }
135
        
136
        /**
137
         * Default Constructor with four parameters: configure the 4 flags
138
         * 
139
         * @param boolean (true -> maintains the position of the items; false -> don't maintains the position of the items)
140
         * @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)
141
         * @param boolean (true -> all items showed will be in alphanumeric ordenation; false -> they don't have to be in alphanumeric ordenation)
142
         * @param boolean (true -> discriminates capital letters from small letters; false -> don't discriminates capital letters from small letters)
143
         */
144
        public JComboBoxSearcheableDynamic(boolean maintain_Position_Items, boolean alphanumeric_Sorted_Searches, boolean all_Alphanumeric_Sorted, boolean key_Sensitive)        {
145
                // Invokes to the parent class constructor                
146
                super();        
147

    
148
                // Sets the options selected by the user
149
                maintainPositionItems = maintain_Position_Items;                
150
                allAlphanumericSorted = all_Alphanumeric_Sorted;
151
                alphanumericSortedSearches = alphanumeric_Sorted_Searches | allAlphanumericSorted; // If allAlphanumericSorted = true -> alphanumericSortedSearches = true
152
                keySensitive = key_Sensitive;
153
                onlyOneColor = false;
154
                showAllItems = false;
155
                
156
                if (!testFlagsConfigurationOK())
157
                        JOptionPane.showMessageDialog(this, PluginServices.getText(this, "error_message_JComboBoxSearcheableDynamic"), PluginServices.getText(this, "exportJOP2Title"), JOptionPane.ERROR_MESSAGE);
158
                else
159
                        this.initializateThisComponent(); // Initializates the current Component variables
160
        }
161

    
162
        /**
163
         * Default Constructor with four parameters: configure the 6 flags
164
         * 
165
         * @param boolean (true -> maintains the position of the items; false -> don't maintains the position of the items)
166
         * @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)
167
         * @param boolean (true -> all items showed will be in alphanumeric ordenation; false -> they don't have to be in alphanumeric ordenation)
168
         * @param boolean (true -> discriminates capital letters from small letters; false -> don't discriminates capital letters from small letters)
169
         * @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
170
         *                           will be showed on red color)
171
           * @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)
172
         */
173
        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) {
174
                // Invokes to the parent class constructor                
175
                super();        
176

    
177
                // Sets the options selected by the user
178
                maintainPositionItems = maintain_Position_Items;                
179
                allAlphanumericSorted = all_Alphanumeric_Sorted;
180
                alphanumericSortedSearches = alphanumeric_Sorted_Searches | allAlphanumericSorted; // If allAlphanumericSorted = true -> alphanumericSortedSearches = true
181
                keySensitive = key_Sensitive;
182
                onlyOneColor = only_One_Color;
183
                showAllItems = show_All_Items;
184
                
185
                if (!testFlagsConfigurationOK())
186
                        JOptionPane.showMessageDialog(this, PluginServices.getText(this, "error_message_JComboBoxSearcheableDynamic"), PluginServices.getText(this, "exportJOP2Title"), JOptionPane.ERROR_MESSAGE);
187
                else
188
                        this.initializateThisComponent(); // Initializates the current Component variables
189
        }
190
        
191
        /**
192
         * Starts all the variables needed for this Component
193
         */
194
        private void initializateThisComponent() {
195
                try
196
                {
197
                        // Allows user to edit on the combobox
198
                        setEditable(true);
199
                        
200
                        // Gets the editor of the combobox_fwAndami
201
                        ComboBoxEditor editor = this.getEditor();
202
                        
203
                        // Gets JTextField of the editor of the combobox
204
                        JTextField textField = (JTextField) editor.getEditorComponent();
205
                        
206
                        // Adds a KeyListener to the JTextField of the editor of the combobox
207
                        textField.addKeyListener(this);
208
                        
209
                        // Disable the focus transversal keys (Example: CTRL+TAB) for enable the TAB key
210
                        textField.setFocusTraversalKeysEnabled(false);
211

    
212
                        // Initialize the Vector with the items
213
                        defaultItems = new Vector();                        
214
                        
215
                        // If we don't have to show all items each time
216
                        if (!showAllItems)
217
                        {
218
                                // Initialize the Set for store the items removed from the JComboBox
219
                                removedItems = new HashSet();
220
                        
221
                                // Initialize the Set for store the items won't be removed from the JComboBox
222
                                if (alphanumericSortedSearches)
223
                                        notRemovedItems = new HashSet();
224
                        }
225
                        
226
                        // By default all items showed aren't sorted
227
                        allItemsAreSorted = false;
228
                        
229
                        // Set the last selected item -> by default any
230
                        lastSelectedItem = -1;
231
                        
232
                }
233
                catch(Exception e)
234
                {
235
                        e.printStackTrace();
236
                }
237
        }
238
        
239
        /**
240
         * This method tests the configuration of the flags and returns true or false if its ok or not with the
241
         *   logical behavior of this component
242
         * 
243
         * @return boolean True if the configuration of the flags is oks, false if not
244
         */
245
        public boolean testFlagsConfigurationOK() {
246
                if ((maintainPositionItems == allAlphanumericSorted) && (maintainPositionItems == true))
247
                        return false;
248
                
249
                if ((maintainPositionItems == false) && (allAlphanumericSorted == true) && (alphanumericSortedSearches == false))
250
                        return false;
251
                
252
                if ((showAllItems == true) && (maintainPositionItems == false))
253
                        return false;
254
                
255
                return true;
256
        }
257

    
258

    
259
        /**
260
         * Redefines the method addItem of the JComboBox
261
         * 
262
         * @param Object the item to add
263
         */
264
        public void addItem(Object anObject) {
265
                // Add the item to this component
266
                super.addItem(anObject);
267
                
268
                // In defaultItems it's saved a copy ordered of the items
269
                defaultItems.add(anObject);
270
                
271
                // If we don't have to show all items each time
272
                if (!showAllItems)
273
                {
274
                        // Store a copy of each item that is in this component
275
                        if (alphanumericSortedSearches)
276
                                notRemovedItems.add(anObject);
277
                }
278
                else
279
                {
280
                        if ((allAlphanumericSorted) && (!allItemsAreSorted))
281
                        {
282
                                this.setModel(this.sortItemsShowed());                
283
                                allItemsAreSorted = true;
284
                        }
285
                }
286
                
287
                // Set the last selected item -> by default any
288
                this.setSelectedIndex(lastSelectedItem);
289
        }
290
        
291
        /**
292
         * This private method makes a copy of items sorted and returns the copy
293
         * 
294
         * @return ComboBoxModel The ComboBoxModel with the copy of the items
295
         */
296
        private ComboBoxModel getCopyOfItems() {
297
                                
298
                DefaultComboBoxModel dCBModel = new DefaultComboBoxModel();
299
                int i;
300

    
301
                Object sorted[] = notRemovedItems.toArray();                                 
302
                Arrays.sort(sorted);
303
                        
304
                // For each item -> makes a copy if hasn't removed
305
                for (i=0; i < sorted.length; i++)
306
                        dCBModel.addElement(sorted[i]);
307
                        
308
                return dCBModel;
309
        }
310
        
311
        /**
312
         * This private method makes a copy of items according to the configuration, this method is invoked when the uses releases the key ESC(APE)
313
         * 
314
         * @return ComboBoxModel The ComboBoxModel with the copy of the items
315
         */
316
        private ComboBoxModel getCopyOfModel() {
317
                
318
                if (maintainPositionItems) // Copies the default items in the same ordenation
319
                {
320
                        DefaultComboBoxModel dCBModel = new DefaultComboBoxModel();
321
                        int i;
322
                        
323
                        // For each item -> makes a copy
324
                        for (i=0; i < defaultItems.size(); i++)
325
                                dCBModel.addElement(defaultItems.get(i));
326
                        
327
                        return dCBModel;
328
                }
329
                else
330
                {
331
                        // Get a copy of the items sorted
332
                        if ((allAlphanumericSorted) || (alphanumericSortedSearches))
333
                        {                        
334
                                DefaultComboBoxModel dCBModel = new DefaultComboBoxModel();
335
                                int i;
336
                                
337
                                Object sorted[] = defaultItems.toArray();
338
                                Arrays.sort(sorted);
339
                                
340
                                // For each item -> makes a copy
341
                                for (i=0; i < sorted.length; i++)
342
                                        dCBModel.addElement(sorted[i]);
343
                                
344
                                return dCBModel;
345
                        }
346
                        else
347
                        {
348
                                // This option isn't used
349
                                return new DefaultComboBoxModel();
350
                        }
351
                }                
352
        }
353

    
354
        /**
355
         * 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 
356
         * 
357
         * @return ComboBoxModel The ComboBoxModel with the copy of the items
358
         */
359
        private ComboBoxModel getCopyOfModelSearched() {
360
                
361
                if (alphanumericSortedSearches) // Copies the items sorted
362
                        return getCopyOfItems();
363
                else
364
                        return this.getModel();
365
        }
366

    
367
        /**
368
         * This private method sorts the items of the vector of the model of this component
369
         * 
370
         * @return ComboBoxModel The ComboBoxModel with the items sorted by alphanumeric order
371
         */
372
        private ComboBoxModel sortItemsShowed()        {
373
                DefaultComboBoxModel dCBModel = new DefaultComboBoxModel();
374
                int i;
375
        
376
                Object sorted[] = defaultItems.toArray();                                 
377
                Arrays.sort(sorted);
378
                        
379
                // For each item -> makes a copy if hasn't removed
380
                for (i=0; i < sorted.length; i++)
381
                        dCBModel.addElement(sorted[i]);
382
                        
383
                return dCBModel;
384
        }
385
        
386
        /**
387
         * 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
388
         * 
389
         * @param String text
390
         * @return int The position of the first coincidence or -1 if hasn't find any coincidence
391
         */
392
        private int findFirstCoincidence(String text) {
393
                int first_position = 0;
394
                boolean matchesTheStart = false;
395
                
396
                // If there is key sensitive
397
                if (keySensitive)
398
                {
399
                        // Find the first match
400
                        while ((first_position < this.getItemCount()) && (matchesTheStart == false))
401
                        {                                        
402
                                if (this.getItemAt(first_position).toString().startsWith(text))
403
                                        matchesTheStart = true;                                                        
404
                                else                                                
405
                                        first_position++; // Increments index
406
                        }                                        
407
                }
408
                else
409
                {
410
                        // If there isn't key sensitive
411
                        
412
                        // Find the first match
413
                        while ((first_position < this.getItemCount()) && (matchesTheStart == false))
414
                        {                                        
415
                                if (this.getItemAt(first_position).toString().toUpperCase().startsWith(text.toUpperCase()))
416
                                        matchesTheStart = true;
417
                                else
418
                                        first_position++; // Increments index
419
                        }
420
                }
421
                
422
                // Return the position value
423
                if (!matchesTheStart)
424
                        return -1;
425
                else
426
                        return first_position;
427
        }
428
        
429
        /**
430
         * Gets the flag of the configuration of the policy for maintain the position of the items of this component 
431
         * (true -> maintains the position of the items, false -> don't maintains the position of the items)
432
         * 
433
         * @return boolean The value of the flag
434
         */
435
        public boolean isMaintainPositionItems() {
436
                return maintainPositionItems;
437
        }
438
        
439
        /**
440
         * Sets the flag of the configuration of the policy for maintain the position of the items of this component 
441
         * (true -> maintains the position of the items, false -> don't maintains the position of the items)
442
         * 
443
         * @param boolean The value of the flag
444
         */
445
        public void setMaintainPositionItems(boolean maintain_Position_Items) {
446
                this.maintainPositionItems = maintain_Position_Items;
447

    
448
                if (!this.testFlagsConfigurationOK())
449
                        JOptionPane.showMessageDialog(this, PluginServices.getText(this, "error_message_JComboBoxSearcheableDynamic"), PluginServices.getText(this, "exportJOP2Title"), JOptionPane.ERROR_MESSAGE);
450
        }
451
        
452
        /**
453
         * Gets the flag of the configuration of the alphanumericSortedSearches flag of this component 
454
         * (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)
455
         * 
456
         * @return boolean The value of the flag
457
         */
458
        public boolean isAlphanumericSortedSearches() {
459
                return alphanumericSortedSearches;
460
        }
461
        
462
        /**
463
         * Sets the flag of the configuration of the alphanumericSortedSearches flag of this component 
464
         * (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)
465
         * 
466
         * @param boolean The value of the flag
467
         */
468
        public void setAlphanumericSortedSearches(boolean alphanumeric_Sorted_Searches) {
469
                this.alphanumericSortedSearches = alphanumeric_Sorted_Searches;
470
                
471
                if (!testFlagsConfigurationOK())
472
                        JOptionPane.showMessageDialog(this, PluginServices.getText(this, "error_message_JComboBoxSearcheableDynamic"), PluginServices.getText(this, "exportJOP2Title"), JOptionPane.ERROR_MESSAGE);
473

    
474
                if (alphanumericSortedSearches)
475
                {
476
                        notRemovedItems = new HashSet();
477
                        
478
                        for (int i=0; i < this.getItemCount(); i++)
479
                                notRemovedItems.add(this.getItemAt(i));
480
                }
481
                else
482
                        notRemovedItems.clear();
483

    
484
        }
485
        
486
        /**
487
         * Gets the flag of the configuration of the allAlphanumericSorted flag of this component 
488
         * (true -> all items showed will be in alphanumeric ordenation; false -> they don't have to be in alphanumeric ordenation)
489
         * 
490
         * @return boolean The value of the flag
491
         */
492
        public boolean isAllAlphanumericSorted() {
493
                return allAlphanumericSorted;
494
        }
495
        
496
        /**
497
         * Sets the flag of the configuration of the allAlphanumericSorted flag of this component 
498
         * (true -> all items showed will be in alphanumeric ordenation; false -> they don't have to be in alphanumeric ordenation)
499
         * 
500
         * @param boolean The value of the flag
501
         */
502
        public void setAllAlphanumericSorted(boolean all_Alphanumeric_Sorted) {
503
                this.allAlphanumericSorted = all_Alphanumeric_Sorted;
504
                
505
                // If all_Alphanumeric_Sorted = true -> alphanumeric_Sorted_Searches = true
506
                setAlphanumericSortedSearches(this.alphanumericSortedSearches | this.allAlphanumericSorted);
507
                
508
                if (allAlphanumericSorted)
509
                
510
                if (!testFlagsConfigurationOK())
511
                        JOptionPane.showMessageDialog(this, PluginServices.getText(this, "error_message_JComboBoxSearcheableDynamic"), PluginServices.getText(this, "exportJOP2Title"), JOptionPane.ERROR_MESSAGE);
512
        }
513
        
514
        /**
515
         * Gets the flag of the configuration of the keySensitive flag of this component 
516
         * (true -> discriminates capital letters from small letters ,false -> don't discriminates capital letters from small letters)
517
         * 
518
         * @return boolean The value of the flag
519
         */
520
        public boolean isKeySensitive() {
521
                return keySensitive;
522
        }
523
        
524
        /**
525
         * Sets the flag of the configuration of the keySensitive flag of this component 
526
         * (true -> discriminates capital letters from small letters ,false -> don't discriminates capital letters from small letters)
527
         * 
528
         * @param boolean The value of the flag
529
         */
530
        public void setKeySensitive(boolean key_Sensitive) {
531
                this.keySensitive = key_Sensitive;
532

    
533
                if (!testFlagsConfigurationOK())
534
                        JOptionPane.showMessageDialog(this, PluginServices.getText(this, "error_message_JComboBoxSearcheableDynamic"), PluginServices.getText(this, "exportJOP2Title"), JOptionPane.ERROR_MESSAGE);
535
        }
536

    
537
        /**
538
         * Gets the flag of the configuration of the onlyOneColor flag of this component
539
         * (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 
540
         *            component -> the text will be showed on red color)
541
         * 
542
         * @return boolean The value of the flag
543
         */
544
        public boolean isOnlyOneColor() {
545
                return onlyOneColor;
546
        }
547

    
548
        
549
        /**
550
         * Sets the flag of the configuration of the onlyOneColor flag of this component 
551
         * (true -> discriminates capital letters from small letters ,false -> don't discriminates capital letters from small letters)
552
         * 
553
         * @param boolean The value of the flag
554
         */
555
        public void setOnlyOneColor(boolean only_One_Color) {
556
                this.onlyOneColor = only_One_Color;
557
                
558
                if (!testFlagsConfigurationOK())
559
                        JOptionPane.showMessageDialog(this, PluginServices.getText(this, "error_message_JComboBoxSearcheableDynamic"), PluginServices.getText(this, "exportJOP2Title"), JOptionPane.ERROR_MESSAGE);
560
        }
561
        
562
        /**
563
         * Gets the flag of the configuration of the showAllItems flag of this component
564
         * (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) 
565
         * 
566
         * @return boolean The value of the flag
567
         */
568
        public boolean isShowAllItems() {
569
                return showAllItems;
570
        }
571

    
572
        /**
573
         * Sets the flag of the configuration of the showAllItems flag of this component
574
         * (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)
575
         * 
576
         * @return boolean The value of the flag
577
         */
578
        public void setShowAllItems(boolean show_All_Items) {
579
                this.showAllItems = show_All_Items;
580
                
581
                if (this.showAllItems == false)
582
                        this.setModel(getCopyOfModel());
583
        }
584
        
585
        
586
        //// IMPLEMENTATION OF THE METHODS OF THE KEYLISTENER ////
587
        
588
        /*
589
         * (non-Javadoc)
590
         * 
591
         * @see java.awt.event.KeyListener#keyTyped(java.awt.event.KeyEvent)
592
         */
593
        public void keyTyped(KeyEvent ke) {
594
        }
595
        
596
        /*
597
         * (non-Javadoc)
598
         * 
599
         * @see java.awt.event.KeyListener#keyPressed(java.awt.event.KeyEvent)
600
         */
601
        public void keyPressed(KeyEvent ke) {
602
        }
603
        
604
        /*
605
         * (non-Javadoc)
606
         * 
607
         * @see java.awt.event.KeyListener#keyReleased(java.awt.event.KeyEvent)
608
         */
609
        public void keyReleased(KeyEvent ke) {
610
                
611
                // Get the JTextField of the Editor of the JComboBox (where the user has written)
612
                // JTextField txtField = (JTextField) ke.getSource();
613
                txtField = (JTextField) ke.getSource();                
614

    
615
                if (ke.getKeyCode() == KeyEvent.VK_DOWN) {
616
                    // 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 
617
                        ComboBoxModel model = this.getModel();
618
                        if ((this.getItemCount() > 0) && (lastSelectedItem == (this.getItemCount()-1))) {
619
                                this.setSelectedIndex(0);
620
                        }
621
                        
622
                        lastSelectedItem = this.getSelectedIndex();
623
                        this.showPopup();
624
                } else if (ke.getKeyCode() == KeyEvent.VK_UP) {
625
                    // 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 
626
                        ComboBoxModel model = this.getModel();
627
                        
628
                        if (lastSelectedItem == 0) {
629
                                this.setSelectedIndex(this.getItemCount()-1);
630
                        }
631
                        
632
                        lastSelectedItem = this.getSelectedIndex();
633
                        this.showPopup();
634
                } else if (ke.getKeyChar() == KeyEvent.VK_ESCAPE) {
635
                        // If the key (typed, pressed and) released has been the Escape Key -> hide the popup list and empty the JTextField                        
636
                        this.hidePopup();
637
                        
638
                        if ((!maintainPositionItems) && (!allAlphanumericSorted))
639
                        {
640
                                if (removedItems.size() > 0)
641
                                {
642
                                        Iterator it = removedItems.iterator();
643
                                        
644
                                        while(it.hasNext())
645
                                                super.addItem(it.next());
646
                                        
647
                                        removedItems.clear();
648
                                }
649
                        }
650
                        else
651
                                this.setModel(getCopyOfModel());
652

    
653
                        txtField.setText("");
654
                        txtField.setForeground(Color.BLACK);
655
                        lastSelectedItem = -1;
656
                        this.setSelectedIndex(lastSelectedItem);
657
                        
658
                } else if (ke.getKeyChar() == KeyEvent.VK_ENTER) {
659
                        // If the key (typed, pressed and) released has been the Enter Key -> hide the popup list and select the characters introduced
660
                        
661
                        //ComboBoxModel model = this.getModel();
662
                        String text = txtField.getText();
663
                        
664
                        if (getSelectedItem() != null) {
665
                                txtField.setText(getSelectedItem().toString());
666
                                
667
                                // Find if the string matches with any item -> if not -> change the foreground color to RED
668
                                if (!onlyOneColor)
669
                                {
670
                                        for (int i=0; i < this.getItemCount(); i++)
671
                                        {
672
                                                if (this.getModel().getElementAt(i).toString().compareTo(text) == 0)
673
                                                {
674
                                                        lastSelectedItem = -1;
675
                                                        this.setSelectedIndex(lastSelectedItem);
676
                                                        txtField.setText(text);
677
                                                        txtField.setForeground(Color.BLACK);
678
                                                        return;
679
                                                }
680
                                        }
681
                                        
682
                                        lastSelectedItem = -1;
683
                                        this.setSelectedIndex(lastSelectedItem);
684
                                        txtField.setText(text);
685
                                        txtField.setForeground(Color.RED);                                        
686
                                }
687
                                else
688
                                        this.getModel().setSelectedItem(getSelectedItem());
689
                        }
690
                } else if (ke.getKeyChar() == Event.BACK_SPACE) {
691
                        // 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
692

    
693
                        int i = 0;
694
                        String s;
695
                        String text = txtField.getText();
696
                        boolean matchesTheStart = false;                        
697
                        
698
                        // If it has to maintain the position of the items
699
                        if (showAllItems)
700
                        {
701
                                int first_match = this.findFirstCoincidence(text);
702
                                
703
                                // If has find a coincidence -> marks the item, else -> reset the index
704
                                this.setSelectedIndex(first_match);
705

    
706
                                txtField.setText(text);
707
                                txtField.setForeground(Color.BLACK);
708
                                lastSelectedItem = this.getSelectedIndex();
709
                                this.showPopup();
710
                                return;
711
                        }
712
                        else
713
                        {
714
                                Object objs[] = removedItems.toArray();
715
                                
716
                                if (alphanumericSortedSearches)
717
                                {
718
                                        if (keySensitive)
719
                                        {
720
                                                // If there is key sensitive
721
                                                while (i < objs.length)
722
                                                {                                        
723
                                                        s = objs[i].toString();
724
                                                        if (s.startsWith(text))
725
                                                        {
726
                                                                removedItems.remove(objs[i]);
727
                                                                notRemovedItems.add(objs[i]);
728
                                                                matchesTheStart = true;
729
                                                        }
730
                                                        
731
                                                        // Increments index
732
                                                        i++;
733
                                                }
734
                                        }
735
                                        else
736
                                        {                                        
737
                                                // If there isn't key sensitive
738
                                                while (i < objs.length)
739
                                                {                                        
740
                                                        s = (objs[i].toString().toUpperCase());
741
                                                        if (s.startsWith(text.toUpperCase()))
742
                                                        {
743
                                                                removedItems.remove(objs[i]);
744
                                                                notRemovedItems.add(objs[i]);
745
                                                                matchesTheStart = true;
746
                                                        }
747
                                                        
748
                                                        // Increments index
749
                                                        i++;
750
                                                }
751
                                        }
752
                                        
753
                                        this.setModel(getCopyOfModelSearched());
754
                                        
755
                                //        if (notRemovedItems.contains(text))
756
                                //                txtField.setForeground(Color.BLACK);
757
                                }
758
                                else
759
                                {
760
                                        this.hidePopup();
761
                                        
762
                                        // If it hasn't to maintain the position of the items
763
                                        if (keySensitive)
764
                                        {
765
                                                // If there is key sensitive
766
                                                while (i < objs.length)
767
                                                {
768
                                                        s = objs[i].toString();
769
                                                        if (s.startsWith(text))
770
                                                        {
771
                                                                removedItems.remove(objs[i]);
772
                                                                super.addItem(objs[i]);
773
                                                                matchesTheStart = true;
774
                                                        }
775
                                
776
                                                        // Increments index
777
                                                        i++;
778
                                                }
779
                                        }
780
                                        else
781
                                        {
782
                                                // If there isn't key sensitive
783
                                                while (i < objs.length)
784
                                                {
785
                                                        s = (objs[i].toString().toUpperCase());                                                
786
                                                                                                        
787
                                                        if (s.startsWith(text.toUpperCase()))
788
                                                        {
789
                                                                removedItems.remove(objs[i]);
790
                                                                super.addItem(objs[i]);
791
                                                                matchesTheStart = true;
792
                                                        }
793
                                
794
                                                        // Increments index
795
                                                        i++;
796
                                                }
797
                                        }
798
                                }
799
                        }                        
800
                        
801
                        txtField.setText(text);                        
802

    
803
                        if (matchesTheStart)
804
                                txtField.setForeground(Color.BLACK);
805
                        
806
                        lastSelectedItem = this.getSelectedIndex();
807
                        this.showPopup();
808
                } else if (ke.getKeyCode() == KeyEvent.VK_TAB) {
809
                        // 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
810

    
811
                        // If there isn't any item selected and there are items, select and show the first item
812
                        if (this.getModel().getSize() > 0)
813
                        {
814
                                if (!showAllItems)
815
                                {
816
                                        int numItems = this.getItemCount();
817
                                        
818
                                        if (alphanumericSortedSearches)
819
                                        {
820
                                                for (int i=1; i < numItems; i++)
821
                                                {
822
                                                        removedItems.add(this.getModel().getElementAt(1));
823
                                                        notRemovedItems.remove(this.getModel().getElementAt(1));
824
                                                        this.removeItemAt(1);
825
                                                }
826
                                        }
827
                                        else
828
                                        {
829
                                                for (int i=1; i < numItems; i++)
830
                                                {
831
                                                        removedItems.add(this.getModel().getElementAt(1));
832
                                                        this.removeItemAt(1);
833
                                                }                                                        
834
                                        }
835
                                
836
                                        // Show a item
837
                                        this.setSelectedIndex(0);
838
                                }
839
                        }
840
                        else
841
                        {
842
                                txtField.setText(""); // If there isn't any item selected and there aren't items, show anything
843
                                this.setSelectedIndex(-1);
844
                        }
845

    
846
                        lastSelectedItem = this.getSelectedIndex();
847
                        this.hidePopup();                        
848
                } else if (ke.getKeyCode() == KeyEvent.VK_LEFT) {
849
                        // Do nothing
850
                } else if (ke.getKeyCode() == KeyEvent.VK_RIGHT) {
851
                        // Do nothing
852
                } else if (ke.getKeyCode() == KeyEvent.VK_PAGE_DOWN) {
853
                        // Do nothing
854
                } else if (ke.getKeyCode() == KeyEvent.VK_PAGE_UP) {
855
                        // Do nothing
856
            } else if (txtField.getText().trim().equalsIgnoreCase("")) {
857
                        // If the current string in the JTextField of the Editor is an empty string -> hide the popup list and the reset the index
858
                    lastSelectedItem = -1;
859
                        this.setSelectedIndex(lastSelectedItem);
860
                        this.hidePopup();
861
                } else {
862
                        // When the user writtes a new character -> find a item of the list that matches it start with the characters written
863
                        // 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
864

    
865
                        ComboBoxModel model = this.getModel();
866
                        String text = txtField.getText();
867
                                        
868
                        // Try to match the characters written with the start of any string value of item of the list
869
                        int i = 0;
870
                        String s;
871
                        boolean matchesTheStart = false;
872
                        
873
                        // If it has to maintain the position of the items
874
                        if (showAllItems)
875
                        {                                
876
                                txtField.setText(text);                        
877

    
878
                                int first_match = this.findFirstCoincidence(text);
879
                                
880
                                // If has find a coincidence -> marks the item, else -> reset the index
881
                                this.setSelectedIndex(first_match);
882
                                
883
                                // Sets the written text to the text field
884
                                txtField.setText(text);
885
                        
886
                                // If has matched the text written with any item -> set the text on black color
887
                                // else -> set the text on red color
888
                                if (!onlyOneColor)
889
                                {
890
                                        if (first_match > -1)
891
                                                txtField.setForeground(Color.BLACK);
892
                                        else
893
                                                txtField.setForeground(Color.RED);
894
                                }
895
                                
896
                                this.showPopup();
897
                                return;
898
                        }
899
                        else
900
                        {
901
                                if (alphanumericSortedSearches)
902
                                {
903
                                        if (keySensitive)
904
                                        {
905
                                                while (i < model.getSize())
906
                                                {
907
                                                        s = model.getElementAt(i).toString();
908
                                                        
909
                                                        // If matches the start
910
                                                        if (s.startsWith(text)) {
911
                                                                matchesTheStart = true;
912
                                                                                
913
                                                                // Increments index
914
                                                                i++;
915
                                                        }
916
                                                        else
917
                                                        {
918
                                                                // When the characters written doesn't match -> set this characters to red color   
919
                                                                removedItems.add(model.getElementAt(i));
920
                                                                notRemovedItems.remove(model.getElementAt(i));
921
                                                                this.removeItemAt(i);
922
                                                        }                                
923
                                                }
924
                                        }
925
                                        else
926
                                        {
927
                                                while (i < model.getSize())
928
                                                {
929
                                                        s = (model.getElementAt(i).toString().toUpperCase());
930
                                                                                                        
931
                                                        // If matches the start
932
                                                        if (s.startsWith(text.toUpperCase())) {
933
                                                                matchesTheStart = true;
934
                                                                                
935
                                                                // Increments index
936
                                                                i++;
937
                                                        }
938
                                                        else
939
                                                        {
940
                                                                // When the characters written doesn't match -> set this characters to red color   
941
                                                                removedItems.add(model.getElementAt(i));
942
                                                                notRemovedItems.remove(model.getElementAt(i));
943
                                                                this.removeItemAt(i);
944
                                                        }                                
945
                                                }
946
                                        }
947
                                        
948
                                        this.setModel(getCopyOfModelSearched());
949
                                }
950
                                else
951
                                {
952
                                        this.hidePopup();
953
                                        
954
                                        if (keySensitive)
955
                                        {
956
                                                while (i < model.getSize())
957
                                                {
958
                                                        s = model.getElementAt(i).toString();
959
                                                        
960
                                                        // If matches the start
961
                                                        if (s.startsWith(text)) {
962
                                                                matchesTheStart = true;
963
                                                                                
964
                                                                // Increments index
965
                                                                i++;
966
                                                        }
967
                                                        else
968
                                                        {
969
                                                                // When the characters written doesn't match -> set this characters to red color   
970
                                                                removedItems.add(model.getElementAt(i));                                
971
                                                                this.removeItemAt(i);
972
                                                        }                                
973
                                                }
974
                                        }
975
                                        else
976
                                        {
977
                                                while (i < model.getSize())
978
                                                {
979
                                                        s = (model.getElementAt(i).toString().toUpperCase());
980
                                                                                                        
981
                                                        // If matches the start
982
                                                        if (s.startsWith(text.toUpperCase())) {
983
                                                                matchesTheStart = true;
984
                                                                                
985
                                                                // Increments index
986
                                                                i++;
987
                                                        }
988
                                                        else
989
                                                        {
990
                                                                // When the characters written doesn't match -> set this characters to red color   
991
                                                                removedItems.add(model.getElementAt(i));                                
992
                                                                this.removeItemAt(i);
993
                                                        }                                
994
                                                }
995
                                        }
996
                                }
997
                        }
998
                                                                
999
                        // Reset the index
1000
                        if (this.getItemCount() > 0)
1001
                                this.setSelectedIndex(0);
1002
                        else
1003
                                this.setSelectedIndex(-1);
1004
                                
1005
                        // Sets the written text to the text field
1006
                        txtField.setText(text);
1007
                
1008
                        // If has matched the text written with any item -> set the text on black color
1009
                        // else -> set the text on red color
1010
                        if (!onlyOneColor)
1011
                        {
1012
                                if (matchesTheStart)
1013
                                        txtField.setForeground(Color.BLACK);
1014
                                else
1015
                                        txtField.setForeground(Color.RED);
1016
                        }
1017
                        
1018
                        lastSelectedItem = this.getSelectedIndex();
1019
                        this.showPopup();
1020
                }                
1021
        }
1022
}