Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.library / org.gvsig.ui / src / main / java / org / gvsig / gui / beans / comboboxconfigurablelookup / DefaultComboBoxConfigurableLookUpModel.java @ 40561

History | View | Annotate | Download (31.3 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.gui.beans.comboboxconfigurablelookup;
25
/* DefaultComboBoxModel.java --
26
   Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc.
27

28
This file is part of GNU Classpath.
29

30
GNU Classpath is free software; you can redistribute it and/or modify
31
it under the terms of the GNU General Public License as published by
32
the Free Software Foundation; either version 2, or (at your option)
33
any later version.
34

35
GNU Classpath is distributed in the hope that it will be useful, but
36
WITHOUT ANY WARRANTY; without even the implied warranty of
37
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
38
General Public License for more details.
39

40
You should have received a copy of the GNU General Public License
41
along with GNU Classpath; see the file COPYING.  If not, write to the
42
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
43
02110-1301 USA.
44

45
Linking this library statically or dynamically with other modules is
46
making a combined work based on this library.  Thus, the terms and
47
conditions of the GNU General Public License cover the whole
48
combination.
49

50
As a special exception, the copyright holders of this library give you
51
permission to link this library with independent modules to produce an
52
executable, regardless of the license terms of these independent
53
modules, and to copy and distribute the resulting executable under
54
terms of your choice, provided that you also meet, for each linked
55
independent module, the terms and conditions of the license of that
56
module.  An independent module is a module which is not derived from
57
or based on this library.  If you modify this library, you may extend
58
this exception to your version of the library, but you are not
59
obligated to do so.  If you do not wish to do so, delete this
60
exception statement from your version. */
61

    
62
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
63
 *
64
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
65
 *
66
 * This program is free software; you can redistribute it and/or
67
 * modify it under the terms of the GNU General Public License
68
 * as published by the Free Software Foundation; either version 2
69
 * of the License, or (at your option) any later version.
70
 *
71
 * This program is distributed in the hope that it will be useful,
72
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
73
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
74
 * GNU General Public License for more details.
75
 *
76
 * You should have received a copy of the GNU General Public License
77
 * along with this program; if not, write to the Free Software
78
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
79
 *
80
 * For more information, contact:
81
 *
82
 *  Generalitat Valenciana
83
 *   Conselleria d'Infraestructures i Transport
84
 *   Av. Blasco Ib??ez, 50
85
 *   46010 VALENCIA
86
 *   SPAIN
87
 *
88
 *      +34 963862235
89
 *   gvsig@gva.es
90
 *      www.gvsig.gva.es
91
 *
92
 *    or
93
 *
94
 *   IVER T.I. S.A
95
 *   Salamanca 50
96
 *   46005 Valencia
97
 *   Spain
98
 *
99
 *   +34 963163400
100
 *   dac@iver.es
101
 */
102

    
103
import java.io.Serializable;
104
import java.text.Collator;
105
import java.util.ArrayList;
106
import java.util.Arrays;
107
import java.util.Collections;
108
import java.util.Comparator;
109
import java.util.List;
110
import java.util.Locale;
111
import java.util.Vector;
112

    
113
import javax.swing.AbstractListModel;
114
import javax.swing.ComboBoxModel;
115
import javax.swing.DefaultComboBoxModel;
116
import javax.swing.MutableComboBoxModel;
117

    
118
import org.gvsig.gui.beans.comboboxconfigurablelookup.agents.StartsWithLookUpAgent;
119

    
120
/**
121
 * <p>Re-implementation of {@link DefaultComboBoxModel} adapted for the behavior needed to look up items.</p>
122
 * 
123
 * <p>This model has configurable behaviour using flags.</p>
124
 * 
125
 * <p><code>DefaultComboBoxConfigurableLookUpModel</code> represents the model used by a {@link JComboBoxLookUpConfigurable JComboBoxLookUpConfigurable},
126
 *  according the MVC (Model-View-Controller) pattern.</p>
127
 * 
128
 * <p>Flags:
129
 * <ul>
130
 *  <li><b>ItemsOrder:</b> order in which items will be showed: maintain position (according the items were introduced); alphabetical order (according the local rules); or disordered.<br>
131
 *   + <b><i>MAINTAIN_POSITION</i></b>: in the same position as they are stored.<br>
132
 *   + <b><i>ALPHABETICAL_ORDERED</i></b>: in alphabetical order (according a local language rules).<br>
133
 *   + <b><i>MAINTAIN_AGENT_POSITIONS</i></b>: in the same position as the are returned by the look up agent.
134
 *  </li>   
135
 *  <li><b>ShowAllItemsInListBox:</b> show all items in list box always, or only items that match with the text written according the <code>ILookUp</code> agent.<br>
136
 *   + <b><i>SHOW_ALL_ITEMS</i></b>: shows all items of the model always.<br>
137
 *   + <b><i>SHOW_ONLY_MATCHES</i></b>: shows only the items , or only items that match with the text written according the <code>ILookUp</code> agent.
138
 *  </li>
139
 *  <li><b>LanguageRules:</b> language rules (es_ES, en_US, fr_FR, ...)</li>  
140
 *  <li><b>CaseSensitive:</b> consider or ignore the case sensitive looking up the items with the <code>ILookUp</code> agent.<br>
141
 *   + <b><i>CASE_SENSITIVE</i></b>: discriminates between lower and upper cases.<br>
142
 *   + <b><i>CASE_INSENSITIVE</i></b>: doesn't discriminate between lower and upper cases.
143
 *  </li>  
144
 * </ul>
145
 * </p>
146
 * 
147
 * <p>Default flag values are:
148
 *  <ul>
149
 *   <li><b>ItemsOrder:</b> <i>MAINTAIN_AGENT_POSITIONS</i>.</li>
150
 *   <li><b>ShowAllItemsInListBox:</b> <i>false (that's equal to ''SHOW_ONLY_MATCHES'').</li>
151
 *   <li><b>LanguageRules:</b> <i>en_EN (English from England)</i>.</li>
152
 *   <li><b>CaseSensitive:</b> <i>true (that's equal to ''CASE_SENSITIVE'')</i>.</li>
153
 *  </ul>
154
 * </p>
155
 * 
156
 * @see javax.swing.DefaultComboBoxModel
157
 * @see JComboBoxConfigurableLookUp
158
 *  
159
 * @author Pablo Piqueras Bartolom? (pablo.piqueras@iver.es)
160
 * @version 07/02/2008
161
 */
162
public class DefaultComboBoxConfigurableLookUpModel extends AbstractListModel implements ComboBoxModel, MutableComboBoxModel, Serializable, IComboBoxLookUp {
163
        private static final long serialVersionUID = 3514664640086791882L;
164

    
165
        /**
166
     * <p>Storage for the elements in the model's objects.</p>
167
     * 
168
     * <p>All items will be stored according they are introduced.</p>
169
     */
170
    private Vector<Object> objects;
171
 
172
    /**
173
     * <p>Stores the elements of 'objects' in alphabetical order.</p>
174
     * 
175
     * <p>This attribute will be used in the searches.</p>
176
     */
177
    private Vector<Object> alphabeticallyOrdered;
178
  
179
    /**
180
     * <p>The selected item (<code>null</code> indicates no selection).</p>
181
     */
182
    private Object selectedObject = null;
183
    
184
    ///// NEW ATTRIBUTES /////
185

    
186
        /**
187
         * <p>Items that will be visible (displayed).</p>
188
         */
189
        private List<Object> visibleList;
190

    
191
        /**
192
         * <p>Text written.</p>
193
         */
194
        private String textWritten;
195
        
196
        /**
197
         * <p>Agent with the logic for looking up the items of this model, considering the text written.</p>
198
         */
199
        private ILookUp lookUpAgent;
200
        
201
        /**
202
         * <p>Object with utilities for managing vectors.</p>
203
         */
204
        private VectorUtilities vectorUtilities;
205

    
206
        /**
207
         * <p>Determines if will notify all events produced.</p>
208
         */
209
        private boolean eventNotificationEnabled = true; // by default -> true
210

    
211
    ///// END NEW ATTRIBUTES /////
212
        
213
        // CONSTANTS FOR CONFIGURE THE BEHAVIOR
214
        public static final int MAINTAIN_POSITION = 0;
215
        public static final int ALPHABETICAL_ORDERED = 1;
216
        public static final int MAINTAIN_AGENT_POSITIONS = 2;
217
        public static final boolean SHOW_ALL_ITEMS = true;
218
        public static final boolean SHOW_ONLY_MATCHES = false;
219
        public static final boolean CASE_SENSITIVE = true;
220
        public static final boolean CASE_INSENSITIVE = false;
221
        
222
        public static final int DEFAULT_ITEMS_ORDER_CONFIGURATION = MAINTAIN_AGENT_POSITIONS;
223
        public static final boolean DEFAULT_SHOW_ALL_ITEMS_IN_LIST_BOX_CONFIGURATION = SHOW_ONLY_MATCHES;
224
        
225
        public static final String DEFAULT_LANGUAGE_RULES_CONFIGURATION = "en_EN";
226
        public static final boolean DEFAULT_CASE_SENSITIVE_CONFIGURATION = CASE_SENSITIVE;
227
        // END CONSTANTS FOR CONFIGURE THE BEHAVIOR
228
        
229
        // CONFIGURATION FLAGS
230
        /**
231
         * <p>Flag: order in which items will be showed: maintain position (according the items were introduced); alphabetical order (according the local rules); or maintain the elements in
232
         *  the positions the look up agent returned.</p>
233
         */
234
        private int itemsOrder;
235
        
236
        /**
237
         * <p>Flag: show all items in list box always, or only items that match with the text written according the <code>ILookUp</code> agent.</p>
238
         */
239
        private boolean showAllItemsInListBox;
240

    
241
        /**
242
         * <p>Flag: locale rules (es_ES, en_US, fr_FR, ...).</p>
243
         */
244
        private String localeRules;
245

    
246
        /**
247
         * <p>Object that allows compare strings. Stores a flag:</p>
248
         * 
249
         * <p>Flag: consider or ignore the case sensitive looking up the items that match with the text written according the <code>ILookUp</code> agent.</p>
250
         */
251
        private StringComparator stringComparator;
252
        // END FLAGS
253

    
254
    /**
255
     * @see javax.swing.DefaultComboBoxModel#DefaultComboBoxModel()
256
     */
257
    public DefaultComboBoxConfigurableLookUpModel()
258
    {
259
            objects = new Vector<Object>();
260
      
261
            initialize();
262
    }
263
  
264
        /**
265
     * @see javax.swing.DefaultComboBoxModel#DefaultComboBoxModel(java.lang.Object[])
266
     */
267
    public DefaultComboBoxConfigurableLookUpModel(final Object items[])
268
    {
269
            objects = new Vector<Object>(Arrays.asList(items));
270

    
271
            initialize();
272
    }
273
  
274
        /**
275
     * @see javax.swing.DefaultComboBoxModel#DefaultComboBoxModel(java.util.Vector)
276
     */
277
    public DefaultComboBoxConfigurableLookUpModel(Vector<Object> vector)
278
    {
279
            this.objects = new Vector<Object>(vector);
280
 
281
            initialize();
282
    }
283
        
284
        ///// REIMPLEMENTATION OF METHODS /////
285
 
286
    /**
287
     * @see javax.swing.DefaultComboBoxModel#addElement(java.lang.Object)
288
     */
289
        public void addElement(Object object)
290
        {
291
                objects.addElement(object);
292
                vectorUtilities.addAlphabeticallyOrdered(alphabeticallyOrdered, object, stringComparator);
293
     
294
                int index = objects.size() - 1;
295
                
296
                updateVisibleList();
297
                 
298
                if (eventNotificationEnabled)
299
                        fireIntervalAdded(this, index, index);
300
         }
301
 
302
        /**
303
         * @see javax.swing.DefaultComboBoxModel#removeElementAt(int)
304
         */
305
        public void removeElementAt(int index)
306
        {
307
                if ( getElementAt( index ) == selectedObject )
308
                {
309
                        if ( index == 0 ) {
310
                                setSelectedItem( getSize() == 1 ? null : getElementAt( index + 1) );
311
                        }
312
                        else {
313
                                setSelectedItem( getElementAt( index - 1 ) );
314
                        }
315
                }
316
                
317
                Object obj = objects.get(index);
318
                
319
                alphabeticallyOrdered.remove(obj);
320
                objects.removeElementAt(index);
321
                
322
                updateVisibleList();
323

    
324
                if (eventNotificationEnabled)
325
                        fireIntervalRemoved(this, index, index);
326
        }
327
 
328
        /**
329
         * @see javax.swing.DefaultComboBoxModel#insertElementAt(java.lang.Object, int)
330
         */
331
        public void insertElementAt(Object object, int index)
332
        {
333
                objects.insertElementAt(object, index);
334
                vectorUtilities.addAlphabeticallyOrdered(alphabeticallyOrdered, object, stringComparator);
335
                
336
                updateVisibleList();
337

    
338
                if (eventNotificationEnabled)
339
                        fireIntervalAdded(this, index, index);
340
        }
341
 
342
        /**
343
         * @see javax.swing.DefaultComboBoxModel#removeElement(java.lang.Object)
344
         */
345
        public void removeElement(Object object)
346
        {
347
                int index = getIndexOf(object);
348
                
349
                if (index != -1) {
350
                        removeElementAt(index);
351
                }
352
        }
353
 
354
        /**
355
         * @see javax.swing.DefaultComboBoxModel#removeAllElements()
356
         */
357
        public void removeAllElements()
358
        {
359
                selectedObject = null;
360
                int size = objects.size();
361

    
362
                if (size > 0)
363
                {
364
                        objects.removeAllElements();
365
                        alphabeticallyOrdered.removeAllElements();
366
                        
367
                        updateVisibleList();
368
                         
369
                        if (eventNotificationEnabled)
370
                                fireIntervalRemoved(this, 0, size - 1);
371
                }
372
        }
373

    
374
        /**
375
         * @see javax.swing.DefaultComboBoxModel#getSize()
376
         */
377
        public int getSize()
378
        {                
379
                if (visibleList == null)
380
                        return 0;
381
                else
382
                        return visibleList.size();
383
        }
384
        
385
        /**
386
         * @see javax.swing.DefaultComboBoxModel#setSelectedItem(java.lang.Object)
387
         */
388
        public void setSelectedItem(Object anObject)
389
        {
390
                // No item is selected and object is null, so no change required.
391
                if (selectedObject == null && anObject == null)
392
                        return;
393
                
394
                if ( ((selectedObject != null) && (!selectedObject.equals(anObject)))
395
                                || ((selectedObject == null) && (anObject != null)) ) {
396
                
397
                        // Here we know that object is either an item in the objects or null.
398
         
399
                        // Handle the three change cases: selectedObject is null, object is
400
                        // non-null; selectedObject is non-null, object is null;
401
                        // selectedObject is non-null, object is non-null and they're not
402
                        // equal.
403
                        selectedObject = anObject;
404
                        
405
                        if (anObject == null)
406
                                textWritten = null;
407
                        else
408
                                textWritten = anObject.toString();
409
                        
410
                        updateVisibleList();
411
                        
412
                        if (eventNotificationEnabled)
413
                                fireContentsChanged(this, -1, -1);
414
                }
415
        }
416
 
417
        /**
418
         * @see javax.swing.DefaultComboBoxModel#getSelectedItem()
419
         */
420
        public Object getSelectedItem()
421
        {
422
                return selectedObject;
423
        }
424
 
425
        /**
426
         * @see javax.swing.DefaultComboBoxModel#getElementAt(int)
427
         */
428
        public Object getElementAt(int index)
429
        {                
430
                if (visibleList == null)
431
                        return null;
432
                
433
                if (index >= 0 && index < visibleList.size())
434
                        return visibleList.get(index);
435
                else
436
                        return null;
437
        }
438
        
439
        /**
440
         * @see javax.swing.DefaultComboBoxModel#getIndexOf(java.lang.Object)
441
         */
442
        public int getIndexOf(Object object)
443
        {
444
                if (visibleList == null)
445
                        return -1;
446
            
447
                return visibleList.indexOf(object);
448
        }
449

    
450
        ///// END REIMPLEMENTATION OF METHODS /////    
451
    
452
        ///// METHODS FOR THE BEHAVIOR FLAGS  /////
453
        /**
454
         * <p>Returns the 'itemsOrder' configuration value of this component. Configuration values are:
455
         *  <ul>
456
         *   <li>MAINTAIN_POSITION: all items will be shown in the order programmer did.</li>
457
         *   <li>ALPHABETICAL_ORDERED: all items will be shown in alphabetical order.</li>
458
         *   <li>MAINTAIN_AGENT_POSITIONS: all items will be shown in the order the look up agent did.</li>
459
         *  </ul>
460
         * </p>
461
         * 
462
         * @return 'itemsOrder' configuration
463
         */
464
        public int getItemsOrder() {
465
                return itemsOrder;
466
        }
467

    
468
        /**
469
         * <p>Sets the 'itemsOrder' configuration value for this component. Configuration values are:
470
         *  <ul>
471
         *   <li>MAINTAIN_POSITION: all items will be shown in the order programmer did.</li>
472
         *   <li>ALPHABETICAL_ORDERED: all items will be shown in alphabetical order.</li>
473
         *   <li>MAINTAIN_AGENT_POSITIONS: all items will be shown in the order the look up agent did.</li>
474
         *  </ul>
475
         * </p>
476
         * 
477
         * @param An integer value for 'itemsOrder' configuration flag
478
         */
479
        public void setItemsOrder(int itemsOrder) {
480
                this.itemsOrder = itemsOrder;
481
        }
482
        
483
        /**
484
         * <p>Returns the 'showAllItemsInListBox' configuration value of this component. Configuration values are:
485
         *  <ul>
486
         *   <li>SHOW_ALL_ITEMS: shows all items in the list box.</li>
487
         *   <li>SHOW_ONLY_MATCHES: shows only the items that match with the text written according the <code>ILookUp</code> agent.</li>
488
         *  </ul> 
489
         * </p>
490
         * 
491
         * @return 'showAllItemsInListBox' configuration
492
         */
493
        public boolean isShowAllItemsInListBox() {
494
                return showAllItemsInListBox;
495
        }
496
        
497
        /**
498
         * <p>Sets the 'showAllItemsInListBox' configuration value for this component. Configuration values are:
499
         *  <ul>
500
         *   <li>SHOW_ALL_ITEMS: shows all items in the list box.</li>
501
         *   <li>SHOW_ONLY_MATCHES: shows only the items that match with the text written according the <code>ILookUp</code> agent.</li>
502
         *  </ul> 
503
         * </p>
504
         * 
505
         * @param A boolean value for 'showAllItemsInListBox' configuration flag
506
         */
507
        public void setShowAllItemsInListBox(boolean itemsShownInListBox) {
508
                this.showAllItemsInListBox = itemsShownInListBox;
509
        }
510
        
511
        /**
512
         * <p>Returns the 'localeRules' configuration value of this component. The language code values could be consulted at: <br>
513
         *  <i><a href="http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt">http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt</a></i><br>
514
         *  <i><a href="http://www.chemie.fu-berlin.de/diverse/doc/ISO_3166.html">http://www.chemie.fu-berlin.de/diverse/doc/ISO_3166.html</a></i>
515
         * </p>
516
         * 
517
         * @see {@Locale}
518
         * 
519
         * @return 'localeRules' configuration
520
         */
521
        public String getLocaleRules() {
522
                return localeRules;
523
        }
524
        
525
        /**
526
         * <p>Sets the 'localeRules' configuration value for this component. Configuration values are: <br>
527
         *  <i><a href="http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt">http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt</a></i><br>
528
         *  <i><a href="http://www.chemie.fu-berlin.de/diverse/doc/ISO_3166.html">http://www.chemie.fu-berlin.de/diverse/doc/ISO_3166.html</a></i>
529
         * </p>
530
         * 
531
         * @see {@Locale}
532
         * 
533
         * @param An String value for 'localeRules' configuration flag
534
         */
535
        public void setLocaleRules(String localeRules) {
536
                this.localeRules = localeRules;
537
                
538
                stringComparator.setLocaleRules(stringComparator.new LocaleRules(true, Collator.getInstance(new Locale(this.localeRules))));
539
                Collections.sort(alphabeticallyOrdered.subList(0, alphabeticallyOrdered.size()), stringComparator); 
540
                
541
                updateVisibleList();
542
        }
543
        
544
        /**
545
         * <p>Returns the 'caseSensitive' configuration value of this component. Configuration values are:
546
         *  <ul>
547
         *   <li>CASE_SENSITIVE: discriminates between small letters and capital letters.</li>
548
         *   <li>CASE_INSENSITIVE: doesn't discriminates between small letters and capital letters.</li>
549
         *  </ul> 
550
         * </p>
551
         *  
552
         * @return 'caseSensitive' configuration
553
         */
554
        public boolean isCaseSensitive() {
555
                return stringComparator.isCaseSensitive();
556
        }
557
        
558
        /**
559
         * <p>Sets the 'caseSensitive' configuration value for this component. Configuration values are:
560
         *  <ul>
561
         *   <li>CASE_SENSITIVE: discriminates between small letters and capital letters.</li>
562
         *   <li>CASE_INSENSITIVE: doesn't discriminates between small letters and capital letters.</li>
563
         *  </ul> 
564
         * </p>
565
         *  
566
         * @param A boolean value for 'caseSensitive' configuration flag
567
         */
568
        public void setCaseSensitive(boolean caseSensitive) {
569
                stringComparator.setCaseSensitive(caseSensitive);
570
                Collections.sort(alphabeticallyOrdered.subList(0, alphabeticallyOrdered.size()), stringComparator); 
571

    
572
                updateVisibleList();
573
        }
574
        ///// END METHODS FOR THE BEHAVIOR FLAGS  /////
575
    
576
   ///// NEW METHODS /////
577
   
578
        /**
579
         * <p>Initializes some attributes.</p>
580
         */
581
        protected void initialize() {
582
                textWritten = "";
583
                
584
                // Creates an object for doing ordering operations with vectors
585
                vectorUtilities = new VectorUtilities();
586
                
587
                // Creates the agent that will execute the look up on the items of this model
588
                lookUpAgent = new StartsWithLookUpAgent();
589
                
590
                // Initializes the StringComparator -> use spanish alphabetical rules, and case sensitive
591
                stringComparator = new StringComparator();
592
                stringComparator.setCaseSensitive(DEFAULT_CASE_SENSITIVE_CONFIGURATION);
593
                stringComparator.setLocaleRules(stringComparator.new LocaleRules(true, Collator.getInstance(new Locale(DEFAULT_LANGUAGE_RULES_CONFIGURATION))));
594
                
595
                // Set default flags configuration
596
                this.setDefaultBehaviorFlagsConfiguration();                
597
                
598
                alphabeticallyOrdered = new Vector<Object>(objects.subList(0, objects.size()));
599
                Collections.sort(alphabeticallyOrdered.subList(0, alphabeticallyOrdered.size()), stringComparator); // Use an algorithm of comparision which implements the rules of the language.
600
                
601
                visibleList = new ArrayList<Object>();
602
                updateVisibleList();
603
        }
604
        
605
        /**
606
         * <p>Sets the default values of the flags.</p>
607
         */
608
        protected void setDefaultBehaviorFlagsConfiguration() {
609
                itemsOrder = DEFAULT_ITEMS_ORDER_CONFIGURATION;
610
                showAllItemsInListBox = DEFAULT_SHOW_ALL_ITEMS_IN_LIST_BOX_CONFIGURATION;
611
                localeRules = DEFAULT_LANGUAGE_RULES_CONFIGURATION;
612
                stringComparator.setCaseSensitive(DEFAULT_CASE_SENSITIVE_CONFIGURATION);
613
        }
614

    
615
        /**
616
         * <p>Returns all elements stored in this model, according the order they were added.</p>
617
         * 
618
         * @return data stored in this model.
619
         */
620
        public Vector<Object> getData() {
621
                return objects;
622
        }
623

    
624
        /**
625
         * <p>Gets the data stored in this model according the criterion of the <i>itemsOrder</i> parameter.</p>
626
         * <p>Always returns all items stored.</p>
627
         * 
628
         * @return data stored in this model according the criterion of the <i>itemsOrder</i> parameter
629
         */
630
        public Vector<Object> getDataAccordingItemsOrder() {
631
                switch(itemsOrder) {
632
                        case MAINTAIN_POSITION:
633
                                return objects;
634
                     case ALPHABETICAL_ORDERED:
635
                             // Do nothing because items are already alphabetically ordered
636
                             return alphabeticallyOrdered;
637
                     case MAINTAIN_AGENT_POSITIONS:
638
                             List<Object> list;
639
                             
640
                             // "" forces to return all items stored
641
                            if (stringComparator.isCaseSensitive()) {
642
                                    list = lookUpAgent.doLookUpConsideringCaseSensitive("", alphabeticallyOrdered, stringComparator);
643
                            }
644
                            else {
645
                                    list = lookUpAgent.doLookUpIgnoringCaseSensitive("", alphabeticallyOrdered, stringComparator);
646
                            }
647
                            
648
                            return new Vector<Object>(list.subList(0, list.size()));
649
                     default:
650
                             // Default case: ALPHABETICAL_ORDERED
651
                             // Do nothing because items are already alphabetically ordered
652
                             return alphabeticallyOrdered;
653
                }
654
        }
655
        
656
        /**
657
         * <p>Updates the list with the results of the look up by the agent, and its configuration.</p>
658
         */
659
        protected void updateVisibleList() {
660
                if (!eventNotificationEnabled)
661
                        return;
662
                
663
                if (objects.size() == 0) {
664
                        visibleList = alphabeticallyOrdered.subList(0, 0);
665
                        return;
666
                }
667
                
668
                if (showAllItemsInListBox) {
669
                        switch (itemsOrder) {
670
                                case MAINTAIN_POSITION:
671
                                        visibleList = objects.subList(0, objects.size());
672
                                     break;
673
                             case ALPHABETICAL_ORDERED:
674
                                     visibleList = alphabeticallyOrdered.subList(0, alphabeticallyOrdered.size());
675
                                 break;
676
                             case MAINTAIN_AGENT_POSITIONS:
677
                                     // "" forces to return all items stored
678
                                    if (stringComparator.isCaseSensitive()) {
679
                                            visibleList = lookUpAgent.doLookUpConsideringCaseSensitive("", alphabeticallyOrdered, stringComparator);
680
                                    }
681
                                    else {
682
                                            visibleList = lookUpAgent.doLookUpIgnoringCaseSensitive("", alphabeticallyOrdered, stringComparator);
683
                                    }
684
                                     break;
685
                             default:
686
                                     // Default case: ALPHABETICAL_ORDERED
687
                                     visibleList = alphabeticallyOrdered.subList(0, alphabeticallyOrdered.size());
688
                        }
689

    
690
                        if ((visibleList != null) && (visibleList.size() > 0)) {
691
                                List<Object> list = lookUp();
692

    
693
                                if ((list != null) && (list.size() > 0)) {
694
                                        selectedObject = list.get(0);
695
                                        textWritten = selectedObject.toString(); // ?
696
                                }
697
                                else {
698
                                        selectedObject = null;
699
                                }
700
                        }
701
                }
702
                else {
703
                        visibleList = lookUp();
704
                        
705
                        switch (itemsOrder) {
706
                                case MAINTAIN_POSITION:
707
                                        if (visibleList != null) {
708
                                                Vector<Object> aux = new Vector<Object>(objects.subList(0, objects.size()));
709
                                                int size = aux.size();
710
                                                Object obj = new Object();
711

    
712
                                                for (int i = (size - 1); i >= 0; i--) {
713
                                                        obj = aux.get(i);
714

    
715
                                                        if (visibleList.contains(obj)) {
716
                                                                visibleList.remove(obj);
717
                                                        }
718
                                                        else {
719
                                                                aux.remove(i);
720
                                                        }
721
                                                }
722

    
723
                                                visibleList = aux.subList(0, aux.size());
724
                                        }
725
                                     break;
726
                             case ALPHABETICAL_ORDERED:
727
                                     if (visibleList != null)
728
                                             Collections.sort(visibleList, stringComparator);
729
                                     break;
730
                             case MAINTAIN_AGENT_POSITIONS:
731
                                     // Do nothing because items are already ordered
732
                                     break;
733
                             default:
734
                                     // Default case: ALPHABETICAL_ORDERED
735
                                     // Do nothing because items are already alphabetically ordered
736
                        }
737
                }
738
        }
739

    
740
        /**
741
         * <p>Invokes the agent to execute its search on all items alphabetically sort ordered,
742
         *  considering the <i>text written</i> and the <i>case sensitive</i> configuration. The agent will use a <p>Comparator</p> that
743
         *  includes the <i>locale language rules</i> and the <i>case sensitive</i> in the rule that uses to compare.</p>.
744
         * 
745
         * @return java.util.List
746
         */
747
        protected List<Object> lookUp() {
748
                if (stringComparator.isCaseSensitive()) {
749
                        return lookUpAgent.doLookUpConsideringCaseSensitive(textWritten, alphabeticallyOrdered, stringComparator);
750
                }
751
                else {
752
                        return lookUpAgent.doLookUpIgnoringCaseSensitive(textWritten, alphabeticallyOrdered, stringComparator);
753
                }
754
        }
755

    
756
        /**
757
         * <p>Gets the agent used with the logic for looking up the items of this model, considering
758
         *  the text written.</p>
759
         *  
760
         * @return the agent used with the logic for looking up the items of this model
761
         */
762
        public ILookUp getLookUpAgent() {
763
                return lookUpAgent;
764
        }
765

    
766
        /**
767
         * <p>Sets the agent with the logic for looking up the items of this model, considering
768
         *  the text written.</p>
769
         *  
770
         * @param agent the agent used with the logic for looking up the items of this model
771
         */
772
        public void setLookUpAgent(ILookUp agent) {
773
                lookUpAgent = agent;
774
                
775
                // Updates the list using the new agent
776
                updateVisibleList();
777
                
778
        }
779

    
780
        /**
781
         * <p>Sets enabled or disabled the notification of events in this model.</p>
782
         * 
783
         * @param b <code>true</code> to enable, <code>false</code> to disable
784
         */
785
        public void setEventNotificationEnabled(boolean b) {
786
                eventNotificationEnabled = b;
787
        }
788

    
789
        /**
790
         * <p>Gets if the notification of events in this model is enabled.</p>
791
         * 
792
         * @return <code>true</code> is its enabled; <code>false</code> otherwise
793
         */
794
        public boolean getEventNotificationEnabled() {
795
                return eventNotificationEnabled;
796
        }
797
        
798
        ///// END NEW METHODS /////
799

    
800
        ///// REIMPLEMENTATION OF METHODS OF THE INTERFACE IComboBoxLookUp /////
801

    
802
        /*
803
         * (non-Javadoc)
804
         * @see org.gvsig.gui.beans.comboboxconfigurablelookup.IComboBoxLookUp#setTextWritten(java.lang.String)
805
         */
806
        public void setTextWritten(String text) {
807
                textWritten = text;
808
                updateVisibleList();
809
        }
810

    
811
        ///// END REIMPLEMENTATION OF METHODS OF THE INTERFACE IComboBoxLookUp /////
812
        
813
        /**
814
         * <p>New functionality to work with vectors (of elements).</p>
815
         *
816
         * <p>This class is a copy of a class with the same name located in <i>libIverUtiles</i>.
817
         * 
818
         * @author Pablo Piqueras Bartolom? (p_queras@hotmail.com)
819
         */
820
        public class VectorUtilities {
821
                /**
822
                 * <p>Creates a new instance of the class <code>VectorUtilities</code>.</p>
823
                 */
824
                public VectorUtilities() {
825
                }
826
                
827
                /**
828
                 * <p>Adds an item in alphabetical order.</p>
829
                 * 
830
                 * @param v java.util.Vector in alphabetical order.
831
                 * @param obj java.lang.Object
832
                 */
833
                public synchronized void addAlphabeticallyOrdered(Vector<Object> v, Object obj) {
834
                        int size = v.size();
835
                        int currentIteration = 0;
836
                        int index, aux_index;
837
                        int lowIndex = 0;
838
                        int highIndex = size -1;
839
                        int maxNumberOfIterations = (int) log2(size);
840
                        
841
                        // If there are no items
842
                        if (size == 0) {
843
                                v.add(obj);
844
                                return;
845
                        }
846
                        
847
                        while ((lowIndex <= highIndex) && (currentIteration <= maxNumberOfIterations)) {
848
                                index = ( lowIndex + highIndex ) / 2;
849

    
850
                                // If the item in the index position has the same value as obj 
851
                                if (v.get(index).toString().compareTo(obj.toString()) == 0) {
852
                                        v.add(index, obj);
853
                                        return;
854
                                }
855

    
856
                                // If the item in the index position has a lower value than the obj
857
                                if (v.get(index).toString().compareTo(obj.toString()) < 0) {
858
                                        aux_index = index + 1;
859
                                        
860
                                        if ((aux_index) >= size) {
861
                                                v.add(v.size() , obj);
862
                                                return;
863
                                        }
864

    
865
                                        if (v.get(aux_index).toString().compareTo(obj.toString()) > 0) {
866
                                                v.add(aux_index, obj);
867
                                                return;
868
                                        }
869

    
870
                                        lowIndex = aux_index;
871
                                }
872
                                else {
873
                                        // If the item in the index position has a higher value than the obj
874
                                        if (v.get(index).toString().compareTo(obj.toString()) > 0) {
875
                                                aux_index = index - 1;
876
                                                
877
                                                if ((aux_index) < 0) {
878
                                                        v.add(0 , obj);
879
                                                        return;
880
                                                }
881
                                                
882
                                                if (v.get(aux_index).toString().compareTo(obj.toString()) < 0) {
883
                                                        v.add(index, obj);
884
                                                        return;
885
                                                }
886
                                                
887
                                                highIndex = aux_index;
888
                                        }
889
                                }
890
                                
891
                                currentIteration ++;
892
                        }                 
893
                }
894
                
895
                /**
896
                 * <p>Adds an item in alphabetic order using a comparator for compare the objects. The objects must be alhabetically ordered.</p>
897
                 *
898
                 * @param v java.util.Vector in alphabetical order.
899
                 * @param obj java.lang.Object
900
                 * @param comp java.util.Comparator
901
                 */
902
                public synchronized void addAlphabeticallyOrdered(Vector<Object> v, Object obj, Comparator<Object> comp) {
903
                        int size = v.size();
904
                        int currentIteration = 0;
905
                        int index, aux_index;
906
                        int lowIndex = 0;
907
                        int highIndex = size -1;
908
                        int maxNumberOfIterations = (int) log2(size);
909
                        
910
                        // If there are no items
911
                        if (size == 0) {
912
                                v.add(obj);
913
                                return;
914
                        }
915
                        
916
                        while ((lowIndex <= highIndex) && (currentIteration <= maxNumberOfIterations)) {
917
                                index = ( lowIndex + highIndex ) / 2;
918
                                
919
                                // If the item in the index position has the same value as obj 
920
                                if (comp.compare(v.get(index), obj) == 0) {
921
                                        v.add(index, obj);
922
                                        return;
923
                                }
924
                                
925
                                // If the item in the index position has a lower value than the obj
926
                                if (comp.compare(v.get(index), obj) < 0) {
927
                                        aux_index = index + 1;
928
                                        
929
                                        if ((aux_index) >= size) {
930
                                                v.add(v.size() , obj);
931
                                                return;
932
                                        }
933
                                        
934
                                        if (comp.compare(v.get(aux_index), obj) > 0) {
935
                                                v.add(aux_index, obj);
936
                                                return;
937
                                        }
938
                                        
939
                                        lowIndex = aux_index;
940
                                }
941
                                else {
942
                                        // If the item in the index position has a higher value than the obj
943
                                        if (comp.compare(v.get(index), obj) > 0) {
944
                                                aux_index = index - 1;
945
                                                
946
                                                if ((aux_index) < 0) {
947
                                                        v.add(0 , obj);
948
                                                        return;
949
                                                }
950
                                                
951
                                                if (comp.compare(v.get(aux_index), obj) < 0) {
952
                                                        v.add(index, obj);
953
                                                        return;
954
                                                }
955
                                                
956
                                                highIndex = aux_index;
957
                                        }
958
                                }
959
                                
960
                                currentIteration ++;
961
                        }
962
                }
963

    
964
                ///// MATHEMATICAL OPERATIONS /////
965
                /**
966
                 * <p>2-base logarithm of a</p>
967
                 * 
968
                 * @param a The value to do the calculations
969
                 * @return Logarithm in 2 base of 'a'
970
                 */
971
                public double log2(double a) {
972
                        return (Math.log(a) / Math.log(2));
973
                }
974
                
975
                /**
976
                 * <p>2-base logarithm of a, but the result doesn't have decimals (approximated to the integer number most near by below)</p>
977
                 * 
978
                 * @param a The value to do the calculations
979
                 * @return Logarithm in 2 base of 'a', as an integer
980
                 */
981
                public int log2Integer(double a) {
982
                        return (int) Math.floor(log2(a));
983
                }
984
                ///// END MATHEMATICAL OPERATIONS /////
985
        }
986
}