Statistics
| Revision:

svn-gvsig-desktop / trunk / libraries / libUI / src / org / gvsig / gui / beans / swing / jComboBoxItemsSeeker / AbstractDefaultComboBoxItemsSeekerConfigurableModel.java @ 10413

History | View | Annotate | Download (29.5 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 *
19
 * For more information, contact:
20
 *
21
 *  Generalitat Valenciana
22
 *   Conselleria d'Infraestructures i Transport
23
 *   Av. Blasco Ib??ez, 50
24
 *   46010 VALENCIA
25
 *   SPAIN
26
 *
27
 *      +34 963862235
28
 *   gvsig@gva.es
29
 *      www.gvsig.gva.es
30
 *
31
 *    or
32
 *
33
 *   IVER T.I. S.A
34
 *   Salamanca 50
35
 *   46005 Valencia
36
 *   Spain
37
 *
38
 *   +34 963163400
39
 *   dac@iver.es
40
 */
41

    
42
package org.gvsig.gui.beans.swing.jComboBoxItemsSeeker;
43

    
44
import java.util.Vector;
45

    
46
import javax.swing.DefaultComboBoxModel;
47

    
48
import org.apache.log4j.Logger;
49

    
50
/**
51
 * Abstract class with some abstract methods that have to implement the classes which inherit this; and with other implementented methods for
52
 *    initialize the ComboBoxItemsSeekerConfigurableModel and do a binary seach if its needed.
53
 * This class represents a Model of the JComboBoxItemsSeekerConfigurable, extends DefaultComboBoxModel, and can be configurated the items that returns.
54
 * In the MVC (Model-View-Control) pattern, this class represents the Model -> this means that this class returns the data (items), in this case
55
 *     according its configuration and the selected item.
56
 * It could be necessary obtein information about the model of the parent of this class: DefaultComboBoxModel -> there are some methods that allow this.
57
 *     
58
 * The model that represents this class, can be configurable with 3 flags/attributes:
59
 *    - Start Behavior -> Configure how return items at beginning (always returns all items). 
60
 *       + MAINTAIN_ORIGINAL_POSITION_START -> Returns items in the same order as DefaultComboBoxModel (according they were introduced).
61
 *       + ORDERED_START -> Returns items ordered.
62
 *       + DISORDERED_START -> Returns items disordered.
63
 *    - Search Behavior -> Configure how return items when it's searching an item.
64
 *       + MAINTAIN_ORIGINAL_POSITION_ALL_ITEMS_SEARCH -> Returns all items in the same order as DefaultComboBoxModel (according they were introduced).
65
 *       + ORDERED_ALL_ITEMS_SEARCH -> Returns all items ordered
66
 *       + DISORDERED_ALL_ITEMS_SEARCH -> Returns all items disordered
67
 *       + MAINTAIN_ORIGINAL_POSITION_DYNAMIC_SEARCH -> Retuns items that their String value starts with a chain of characters introduced. Items are returned in
68
 *           the same order as DefaultComboBoxModel (according they were introduced).
69
 *       + ORDERED_DYNAMIC_SEARCH -> Retuns items that their String value starts with a chain of characters introduced. Items are returned ordered.
70
 *       + DISORDERED_DYNAMIC_SEARCH -> Retuns items that their String value starts with a chain of characters introduced. Items are returned disordered.
71
 *   - Case Sensitive -> Discriminates capital letters from small letters or not when seeks items
72
 *            + true -> discriminates capital letters from small letters when seeks items
73
 *       + false -> don't discriminates capital letters from small letters when seeks items
74
 *       
75
 * By default the configuration is:
76
 *     - Start_Behavior = MAINTAIN_ORIGINAL_POSITION_START
77
 *     - Search_Behavior = ORDERED_DYNAMIC_SEARCH
78
 *     - Case_Sensitive = false
79
 * 
80
 * @author Pablo Piqueras Bartolom? (p_queras@hotmail.com)
81
 */
82
public abstract class AbstractDefaultComboBoxItemsSeekerConfigurableModel extends DefaultComboBoxModel {
83
        // INNER MODEL STRUCTURES
84
        protected Object itemsSearchesShow[];
85
        // END INNER MODEL STRUCTURES
86
        
87
        // TRACE - DEBUG
88
        protected Logger logger = Logger.getLogger(AbstractDefaultComboBoxItemsSeekerConfigurableModel.class.getClass());
89
        // END TRACE - DEBUG
90
        
91
        // CONTANTS FOR CONFIGURE THE BEHAVIOR
92
        public static final int MAINTAIN_ORIGINAL_POSITION_START = 0;
93
        public static final int ORDERED_START = 1;
94
        public static final int DISORDERED_START = 2;
95

    
96
        public static final int MAINTAIN_ORIGINAL_POSITION_ALL_ITEMS_SEARCH = 3;
97
        public static final int ORDERED_ALL_ITEMS_SEARCH = 4;
98
        public static final int DISORDERED_ALL_ITEMS_SEARCH = 5;
99
        public static final int MAINTAIN_ORIGINAL_POSITION_DYNAMIC_SEARCH = 6;
100
        public static final int ORDERED_DYNAMIC_SEARCH = 7;
101
        public static final int DISORDERED_DYNAMIC_SEARCH = 8;
102
        
103
        public static final int DEFAULT_START_BEHAVIOR_CONFIGURATION = MAINTAIN_ORIGINAL_POSITION_START;
104
        public static final int DEFAULT_SEARCH_BEHAVIOR_CONFIGURATION = ORDERED_DYNAMIC_SEARCH;
105
        public static final boolean DEFAULT_CASE_SENSITIVE_CONFIGURATION = false;
106
        // END CONTANTS FOR CONFIGURE THE BEHAVIOR
107
        
108
        // CONFIGURATION FLAGS
109
        protected int startBehavior;
110
        protected int searchBehavior;
111
        protected boolean caseSensitive_Flag;
112
        // END FLAGS
113

    
114
        // FLAGS AND ATTRIBUTES FOR THE CURRENT STATE
115
        protected int stateAllItems;        
116
        protected final int STATE_DEFAULT = 10;
117
        protected final int STATE_ITEMS_ARE_ORDERED = 11;
118
        protected final int STATE_ITEMS_ARE_DISORDERED = 12;
119
        // FLAGS AND ATTRIBUTES FOR THE CURRENT STATE        
120
        
121
        // OTHER FLAGS
122
        protected boolean startState;
123
        protected boolean dynamicSearchDone;
124
        protected boolean itemsInTheArray;
125
        // END OTHER FLAGS
126

    
127
        // ATTRIBUTES FOR DYNAMIC CASES
128
        protected String writtenText;
129
        // END ATTRIBUTES FOR DYNAMIC CASES
130
        
131
        // OTHER OBJECTS
132
        protected Object moreSimilarItemToLastWrittenText;
133
        // OTHER OBJECTS
134
        
135
        /** 
136
         * @see DefaultComboBoxModel#DefaultComboBoxModel()
137
         */
138
        public AbstractDefaultComboBoxItemsSeekerConfigurableModel() {
139
                super();
140
        }
141
        
142
        /** 
143
         * @see DefaultComboBoxModel#DefaultComboBoxModel(Object[])
144
         */
145
        public AbstractDefaultComboBoxItemsSeekerConfigurableModel(Object[] items) {                
146
                super(items);
147
        }
148

    
149
        /**
150
         * @see DefaultComboBoxModel#DefaultComboBoxModel(Vector)
151
         */
152
        public AbstractDefaultComboBoxItemsSeekerConfigurableModel(Vector objects) {
153
                super(objects);
154
        }
155
        
156
        /**
157
         * This method sets the start values of inner attributes and creates the necessary inner objects
158
         */
159
        protected void initialize() {
160
                this.writtenText = "";
161
                this.setDefaultBehaviorFlagsConfiguration();
162
                this.startState = true;
163
                this.stateAllItems = STATE_DEFAULT;
164

    
165
                this.dynamicSearchDone = false; 
166
                this.itemsInTheArray = false;
167
        }
168
        
169
        /**
170
         * Method that sets the default values of the behavior flags
171
         */
172
        protected void setDefaultBehaviorFlagsConfiguration() {
173
                // Set the default values of the flags
174
                this.startBehavior = DEFAULT_START_BEHAVIOR_CONFIGURATION;
175
                this.searchBehavior = DEFAULT_SEARCH_BEHAVIOR_CONFIGURATION;
176
                this.caseSensitive_Flag = DEFAULT_CASE_SENSITIVE_CONFIGURATION;
177
        }
178
        
179
        ////// METHODS FOR THE BEHAVIOR FLAGS  //////
180
        
181
        /**
182
         * This method tests the configuration of the behavior flags and returns true or false if its ok or not
183
         * 
184
         * @return boolean True if the configuration of the flags is oks, false if not
185
         */
186
        public boolean testFlagsConfigurationOK() {
187
                if ((this.startBehavior < 0) || (this.startBehavior > 2))
188
                        return false;
189
                
190
                if ((this.searchBehavior < 3) || (this.searchBehavior > 8))
191
                        return false;
192
                
193
                return true;
194
        }
195

    
196
        /**
197
         * Retuns the 'start_Behavior' configuration of this model. Configuration values are:
198
     *    + MAINTAIN_ORIGINAL_POSITION_START -> Returns items in the same order as DefaultComboBoxModel (according they were introduced).
199
     *    + ORDERED_START -> Returns items ordered.
200
     *    + DISORDERED_START -> Returns items disordered.
201
         * 
202
         * @return 'start_Behavior' configuration
203
         */
204
        public int getStartBehavior() {
205
                return this.startBehavior;
206
        }
207
        
208
        /**
209
         * Sets the 'start_Behavior' configuration for this model. Configuration values are:
210
     *    + MAINTAIN_ORIGINAL_POSITION_START -> Returns items in the same order as DefaultComboBoxModel (according they were introduced).
211
     *    + ORDERED_START -> Returns items ordered.
212
     *    + DISORDERED_START -> Returns items disordered.
213
         * 
214
         * @oaram An integer value for 'start_Behavior' configuration flag
215
         */
216
        public void setStartBehavior(int start_Behavior) {
217
                this.startBehavior = start_Behavior;                
218
        }
219

    
220
        /**
221
         * Retuns the 'search_Behavior' configuration of this model. Configuration values are:
222
     *    + MAINTAIN_ORIGINAL_POSITION_ALL_ITEMS_SEARCH -> Returns all items in the same order as DefaultComboBoxModel (according they were introduced).
223
     *    + ORDERED_ALL_ITEMS_SEARCH -> Returns all items ordered
224
     *    + DISORDERED_ALL_ITEMS_SEARCH -> Returns all items disordered
225
     *    + MAINTAIN_ORIGINAL_POSITION_DYNAMIC_SEARCH -> Retuns items that their String value starts with a chain of characters introduced. Items are returned in
226
     *        the same order as DefaultComboBoxModel (according they were introduced).
227
     *    + ORDERED_DYNAMIC_SEARCH -> Retuns items that their String value starts with a chain of characters introduced. Items are returned ordered.
228
     *    + DISORDERED_DYNAMIC_SEARCH -> Retuns items that their String value starts with a chain of characters introduced. Items are returned disordered.
229
         * 
230
         * @return 'search_Behavior' configuration
231
         */
232
        public int getSearchBehavior() {
233
                return this.searchBehavior;
234
        }
235

    
236
        /**
237
         * Sets the 'search_Behavior' configuration for this model. Configuration values are:
238
     *   + MAINTAIN_ORIGINAL_POSITION_ALL_ITEMS_SEARCH -> Returns all items in the same order as DefaultComboBoxModel (according they were introduced).
239
     *   + ORDERED_ALL_ITEMS_SEARCH -> Returns all items ordered
240
     *   + DISORDERED_ALL_ITEMS_SEARCH -> Returns all items disordered
241
     *   + MAINTAIN_ORIGINAL_POSITION_DYNAMIC_SEARCH -> Retuns items that their String value starts with a chain of characters introduced. Items are returned in
242
     *       the same order as DefaultComboBoxModel (according they were introduced).
243
     *   + ORDERED_DYNAMIC_SEARCH -> Retuns items that their String value starts with a chain of characters introduced. Items are returned ordered.
244
     *   + DISORDERED_DYNAMIC_SEARCH -> Retuns items that their String value starts with a chain of characters introduced. Items are returned disordered.
245
         * 
246
         * @oaram An integer value for 'search_Behavior' configuration flag
247
         */
248
        public void setSearchBehavior(int search_Behavior) {
249
                this.searchBehavior = search_Behavior;
250
        }
251

    
252
        /**
253
         * Returns the 'case_Sensitive' configuration value of this model. Configuration values are: 
254
         *   + true -> discriminates capital letters from small letters when seeks items
255
         *   + false -> don't discriminates capital letters from small letters when seeks items
256
         * 
257
         * @return 'case_Sensitive' configuration
258
         */
259
        public boolean isCaseSensitive_Flag() {
260
                return caseSensitive_Flag;
261
        }
262
        
263
        /**
264
         * Sets the 'case_Sensitive' configuration value for this model. Configuration values are: 
265
         *   + true -> discriminates capital letters from small letters when seeks items
266
         *   + false -> don't discriminates capital letters from small letters when seeks items
267
         * 
268
         * @oaram A boolean value for 'case_Sensitive' configuration flag
269
         */
270
        public void setCaseSensitive_Flag(boolean case_Sensitive) {
271
                this.caseSensitive_Flag = case_Sensitive;
272
        }
273

    
274
        ////// END METHODS FOR THE BEHAVIOR FLAGS //////
275
        
276

    
277
        
278
        ////// REIMPLEMENTATION OF SOME METHODS OF "DefaultComboBoxModel" TO ADAPT THE BEHAVIOR OF THIS MODEL //////        
279
        
280
        /*
281
         *  (non-Javadoc)
282
         * @see javax.swing.DefaultComboBoxModel#getSize()
283
         */
284
        public abstract int getSize();        
285

    
286
        /*
287
         *  (non-Javadoc)
288
         * @see javax.swing.ListModel#getElementAt(int)
289
         */
290
        public abstract Object getElementAt(int index);
291

    
292
        /*
293
         *  (non-Javadoc)
294
         * @see javax.swing.DefaultComboBoxModel#getIndexOf(java.lang.Object)
295
         */
296
        public abstract int getIndexOf(Object anObject);
297
        
298
    /*
299
     *  (non-Javadoc)
300
     * @see javax.swing.ComboBoxModel#getSelectedItem()
301
     */
302
        public Object getSelectedItem() {
303
                return super.getSelectedItem();
304
        }
305
        
306
        /*
307
         *  (non-Javadoc)
308
         * @see javax.swing.MutableComboBoxModel#addElement(java.lang.Object)
309
         */
310
        public abstract void addElement(Object anObject);
311
        
312
        /*
313
         *  (non-Javadoc)
314
         * @see javax.swing.MutableComboBoxModel#insertElementAt(java.lang.Object, int)
315
         */
316
        public abstract void insertElementAt(Object anObject, int index);
317

    
318
        /*
319
         *  (non-Javadoc)
320
         * @see javax.swing.DefaultComboBoxModel#removeAllElements()
321
         */
322
        public abstract void removeAllElements();
323
    
324
        /*
325
         *  (non-Javadoc)
326
         * @see javax.swing.MutableComboBoxModel#removeElement(java.lang.Object)
327
         */
328
        public abstract void removeElement(Object anObject);
329
        
330
        /*
331
         *  (non-Javadoc)
332
         * @see javax.swing.MutableComboBoxModel#removeElementAt(int)
333
         */
334
        public abstract void removeElementAt(int index);
335
        
336
        ////// END REIMPLEMENTATION OF SOME METHODS OF "DefaultComboBoxModel" TO ADAPT THE BEHAVIOR OF THIS MODEL //////        
337

    
338
        
339
        
340
        ////// USE OF SOME METHODS OF "DefaultComboBoxModel" //////        
341
        
342
        /**
343
     * @see DefaultComboBoxModel#getSize()
344
         */
345
        public int getParentSize() {
346
                return super.getSize();
347
        }
348
        
349
        /**
350
         * @see javax.swing.MutableComboBoxModel#addElement(java.lang.Object)
351
         */
352
        protected void addElementToParent(Object anObject) {
353
                super.addElement(anObject);
354
        }
355
        
356
        /**
357
         * @see javax.swing.ListModel#getElementAt(int)
358
         */
359
        protected Object getParentElementAt(int index) {
360
                return super.getElementAt(index);
361
        }
362
        
363
        /**
364
         * @see javax.swing.DefaultComboBoxModel#getIndexOf(java.lang.Object)
365
         */
366
        protected int getParentIndexOf(Object anObject) {
367
                return super.getIndexOf(anObject);
368
        }
369
        
370
        /**
371
         * @see javax.swing.MutableComboBoxModel#insertElementAt(java.lang.Object, int)
372
         */
373
        protected void insertToParentElementAt(Object anObject, int index) {
374
                super.insertElementAt(anObject, index);
375
        }
376
        
377
        /**
378
         * @see javax.swing.DefaultComboBoxModel#removeAllElements()
379
         */
380
        protected void removeAllElementsOfParent() {
381
                super.removeAllElements();
382
        }
383
        
384
        /**
385
         * @see javax.swing.MutableComboBoxModel#removeElement(java.lang.Object)
386
         */
387
        protected void removeParentElement(Object anObject) {
388
                super.removeElement(anObject);
389
        }
390
        
391
        /**
392
         * @see javax.swing.MutableComboBoxModel#removeElementAt(int)
393
         */
394
        protected void removeParentElementAt(int index) {
395
                // TODO Auto-generated method stub
396
                super.removeElementAt(index);
397
        }
398

    
399
        ////// END USE OF SOME METHODS OF "DefaultComboBoxModel" //////        
400

    
401
        
402
        
403
        ////// OTHER METHODS //////
404
        
405
        /**
406
         * Returns all items that are stored in the model.
407
         * Caution! : this operation could be slow
408
         */
409
        public abstract Vector getParentAllData();
410
        
411
        /**
412
         * Returns the first item added
413
         *  
414
         * @return An item
415
         */
416
        public Object getFirstItemAdded() {
417
        
418
                return super.getElementAt(0);
419
        }
420
        
421
        /**
422
         * Sets a text for seek items
423
         */
424
        public void setWrittenText(String text) {
425
                this.writtenText = text;
426
                this.reset();
427
        }
428
        
429
        /**
430
         * Returns the item of the model that its text value is more similar to the written text, or null
431
         * 
432
         * @return An Item or null
433
         */
434
        public Object getMoreSimilarItemToLastWrittenText() {
435
                int size = getSize();
436
                
437
                if (size == 0)
438
                        return null;
439
                else {
440
                        moreSimilarItemToLastWrittenText = getElementAt(0);
441
                        return moreSimilarItemToLastWrittenText;
442
                }
443
        }
444
        
445
        /**
446
         * Indicates to this model that now has to be or not in the 'start' state.
447
         * If 'flagValue' is true:  items returned will be according the 
448
         *    start-behavior configuration.
449
         * 
450
         * @param flagValue A boolean value.
451
         */
452
        public void setStartStateFlag(boolean flagValue) {
453
                this.startState = flagValue;
454
                this.reset();
455
        }
456
        
457
        /**
458
         * Returns if now the model is in the 'start' state or not
459
         * 
460
         * @return True or false if now the model is in the 'start' state or not
461
         */
462
        public boolean isStartStateFlag() {
463
                return this.startState;
464
        }
465
        
466
        /**
467
         * Resets some inner configuration flags to their default value
468
         */
469
        protected void reset() {
470
                if (this.stateAllItems != STATE_DEFAULT)
471
                {
472
                        this.stateAllItems = STATE_DEFAULT;
473
                        this.dynamicSearchDone = false;
474
                        this.itemsInTheArray = false;
475
                }
476
        }
477
        
478
        /**
479
         * Returns true of false if the configuration of the search is dynamic search or not
480
         * @return True of false if the configuration of the search is dynamic search or not
481
         */
482
        public boolean isDynamicSearch() {
483
                if ((this.searchBehavior > 5) && (this.searchBehavior < 9))
484
                        return true;
485
                else
486
                        return false;
487
        }
488
        
489
        /**
490
         * With this method the model does a dynamic items seek
491
         */
492
        protected abstract void seekDynamicItems();        
493

    
494
        /**
495
         * Returns if the items returned are disordered
496
         * 
497
         * @return If the items returned are disordered
498
         */
499
        public boolean nowItemsAreDisordered() {
500
                if (this.startState)
501
                {
502
                        if (getStartBehavior() == DISORDERED_START)
503
                                return true;
504
                }
505
                else
506
                {
507
                        if ((getSearchBehavior() == DISORDERED_DYNAMIC_SEARCH) || (getSearchBehavior() == DISORDERED_ALL_ITEMS_SEARCH))
508
                                return true;
509
                }
510
                
511
                return false;
512
        }
513
        
514
        /**
515
         * Gets an array with all items that will return/show the model. It's used in dynamic searches.
516
         * 
517
         * @param search An special binary of items search object.
518
         * @param lowIndex Low index of the rank of items to extract from the search object.
519
         * @param hightIndex Hight index of the rank of items to extract from the search object.
520
         */
521
        protected abstract void getDynamicItemsSearch(BinaryRankOfItemsSeek search, int lowIndex, int hightIndex);        
522
        
523
        /**
524
         * Copies items from a search into an array
525
         */
526
        protected abstract void setItemsCopyToArray();
527
        
528
        /**
529
         * This method disorders the items and stores them in an array
530
         */
531
        protected abstract void disorderItemsCopy();
532
        
533
        ////// END OTHER METHODS //////
534
        
535
        
536
        /**
537
         * Inner class for items seek.
538
         * Considers that lowcases and uppercases words/senteces could be in differents ranks.
539
         * Has some modifications of bynary-search-algorithm for obtein the low and high indexes of the lowcase and uppercase ranks. Not always there
540
         *    are the two ranks, it depends on the 'case-sensitive' flag.
541
         * 
542
     * @author Pablo Piqueras Bartolom? (p_queras@hotmail.com)
543
         */
544
        protected class BinaryRankOfItemsSeek {
545
                private int lowIndex;
546
                private int hightIndex;
547
                private int lowIndexSubSet2; // Only used for not caseSensitive case
548
                private int hightIndexSubSet2; // Only used for not caseSensitive case
549
                
550
                /**
551
                 * Default constructor
552
                 */
553
                public BinaryRankOfItemsSeek() {
554
                        // By default -> no search has been made
555
                        this.lowIndex = -1;
556
                        this.hightIndex = -1;
557
                        this.lowIndexSubSet2 = -1;
558
                        this.hightIndexSubSet2 = -1;
559
                }
560
        
561
                /**
562
                 * This method has the algoritms for obtein the low and high rank indexes for 2 ranks: one for items that start in a capital letter
563
                 *    and other which start in a small letter. It also could use different algorithm/s if it's needed differenciate uppercases and
564
                 *    lowercases or not. If its needed to differenciate: there are 2 ranks, else there is only one rank.
565
                 * Uses the beginning of the word/sentece ('writtenText' attribute) for match its start with the start of all items ordered in a/some
566
                 *     binary algorithm, and obtein the indexes of the 2 ranks.
567
                 */
568
                public void binaryRankSeek() {
569
                        boolean continueInLoop = true;
570
                        int mediumIndex;
571
                        int maxNumberOfIterations = (int) MathExtensionReduced.log2(itemsSearchesShow.length);
572
                        logger.debug("Number of iterations: " + maxNumberOfIterations);
573
                        int currentIteration = 0;
574
                                
575
                        this.lowIndex = 0;
576
                        this.hightIndex = itemsSearchesShow.length - 1;
577
                        
578
                        // First -> Find the first item that match its start (This is an iterational version of the binarySearch algorithm)
579
                        if (isCaseSensitive_Flag())
580
                        {
581
                                // Iterational version of a binary search of the first item that it start matches with a text
582
                                while (continueInLoop)
583
                                {
584
                                        // If can't continue searching (item hasn't been found) (With this condition we avoid infinites loops)
585
                                        if (currentIteration > maxNumberOfIterations)
586
                                        {
587
                                                this.lowIndex = this.hightIndex + 1; // Force not show any item after
588
                                                continueInLoop = false;                                                        
589
                                        }
590
                                        else
591
                                        {
592
                                                mediumIndex = (int) Math.floor((this.lowIndex + this.hightIndex) / 2);
593
                                                                                        
594
                                                // If has find the first item that mathes its start
595
                                                if (itemsSearchesShow[mediumIndex].toString().startsWith(writtenText))
596
                                                {
597
                                                        this.lowIndex = this.hightIndex = mediumIndex;
598
                                                        continueInLoop = false;
599
                                                }
600
                                                else
601
                                                {
602
                                                        // Reduce the rank of search
603
                                                        if (itemsSearchesShow[mediumIndex].toString().compareTo(writtenText) > 0)
604
                                                                this.hightIndex = mediumIndex - 1;                                                        
605
                                                        else
606
                                                                this.lowIndex = mediumIndex + 1;
607
                                                        
608
                                                        // If can't continue searching (item hasn't been found)
609
                                                        if (this.lowIndex > this.hightIndex)
610
                                                                continueInLoop = false;                                                        
611
                                                        else
612
                                                                currentIteration ++;
613
                                                }
614
                                        }
615
                                }
616
                                
617
                                logger.debug("BINARY-SEARCH: Low-Index: " + this.lowIndex + "; Hight-Index: " + this.hightIndex);
618
                        }
619
                        else
620
                        {        
621
                                // Elements are ordered in this order -> First UpperCases, Second Simbols, Third LowerCases (left -> right character priority)
622
                                
623
                                // Get The first SubSet
624
                                // Iterational version of a binary search of the first item that its start matches with a text
625
                                while (continueInLoop)
626
                                {
627
                                        // If can't continue searching (item hasn't been found) (With this condition we avoid infinites loops)
628
                                        if (currentIteration > maxNumberOfIterations)
629
                                        {
630
                                                this.lowIndex = this.hightIndex + 1; // Force not show any item after
631
                                                continueInLoop = false;                                                        
632
                                        }
633
                                        else
634
                                        {
635
                                                mediumIndex = (int) Math.floor((this.lowIndex + this.hightIndex) / 2);
636
                                                                                        
637
                                                // If has find the first item that mathes its start
638
                                                if (itemsSearchesShow[mediumIndex].toString().toUpperCase().startsWith(writtenText.toUpperCase()))
639
                                                {
640
                                                        this.lowIndex = this.hightIndex = mediumIndex;
641
                                                        continueInLoop = false;
642
                                                }
643
                                                else
644
                                                {
645
                                                        // Reduce the rank of search
646
                                                        if (itemsSearchesShow[mediumIndex].toString().compareToIgnoreCase(writtenText) > 0) // da problemas
647
                                                                this.hightIndex = mediumIndex - 1;                                                        
648
                                                        else
649
                                                                this.lowIndex = mediumIndex + 1;
650
                                                        
651
                                                        // If can't continue searching (item hasn't been found)
652
                                                        if (this.lowIndex > this.hightIndex)
653
                                                                continueInLoop = false;                                                        
654
                                                        else
655
                                                                currentIteration ++;
656
                                                }
657
                                        }
658
                                }
659
                        
660
                                logger.debug("BINARY-SEARCH-FirstSubSet: Low-Index: " + this.lowIndex + "; Hight-Index: " + this.hightIndex);
661
                                
662
                                
663
                                // THE SECOND SUBSET HAS TO SEEK OLY THE ITEMS THAT START IN CAPITAL LETTERS
664
                                // Get The second SubSet
665
                                continueInLoop = true;
666
                                currentIteration = 0;
667
                                this.lowIndexSubSet2 = 0;
668
                                this.hightIndexSubSet2 = itemsSearchesShow.length - 1;
669

    
670
                                // Iterational version of a binary search of the first item that its start matches with a text
671
                                // In this case tries to find a subset of items that ther string value start with uppercase
672
                                while (continueInLoop)
673
                                {
674
                                        // If can't continue searching (item hasn't been found) (With this condition we avoid infinites loops)
675
                                        if (currentIteration > maxNumberOfIterations)
676
                                        {
677
                                                this.lowIndexSubSet2 = this.hightIndexSubSet2 + 1; // Force not show any item after
678
                                                continueInLoop = false;                                                        
679
                                        }
680
                                        else
681
                                        {
682
                                                mediumIndex = (int) Math.floor((this.lowIndexSubSet2 + this.hightIndexSubSet2) / 2);
683
                                                                                        
684
                                                // If has find the first item that mathes its start
685
                                                if (itemsSearchesShow[mediumIndex].toString().toUpperCase().startsWith(writtenText.toUpperCase()))
686
                                                {
687
                                                        this.lowIndexSubSet2 = this.hightIndexSubSet2 = mediumIndex;
688
                                                        continueInLoop = false;
689
                                                }
690
                                                else
691
                                                {
692
                                                        // Reduce the rank of search
693
                                                        if (itemsSearchesShow[mediumIndex].toString().compareTo(writtenText.toUpperCase()) > 0) // da problemas
694
                                                                this.hightIndexSubSet2 = mediumIndex - 1;                                                        
695
                                                        else
696
                                                                this.lowIndexSubSet2 = mediumIndex + 1;
697
                                                        
698
                                                        // If can't continue searching (item hasn't been found)
699
                                                        if (this.lowIndexSubSet2 > this.hightIndexSubSet2)
700
                                                                continueInLoop = false;                                                        
701
                                                        else
702
                                                                currentIteration ++;
703
                                                }
704
                                        }
705
                                }
706
                                
707
                                logger.debug("BINARY-SEARCH-SecondSubSet: Low-Index: " + this.lowIndexSubSet2 + "; Hight-Index: " + this.hightIndexSubSet2);
708
                                
709
                                // Force not do another search of rank of items
710
                                if ((lowIndex == lowIndexSubSet2) && (hightIndex == hightIndexSubSet2))
711
                                        lowIndexSubSet2 = hightIndexSubSet2 + 1;
712
                        }
713
                                        
714
                        
715
                        // Second -> if indexes are the same -> search the rank of items (items are ordered in the 'itemsSearchesShow' array
716
                        if (this.lowIndex == this.hightIndex)
717
                        {                                
718
                                
719
                                if (isCaseSensitive_Flag())
720
                                {
721
                                        // Seek down
722
                                        this.lowIndex --;
723
                                        if (this.lowIndex > -1)
724
                                                continueInLoop = true;
725
                                        else
726
                                                continueInLoop = false;
727

    
728
                                        while (continueInLoop)
729
                                        {
730
                                                if (!itemsSearchesShow[this.lowIndex].toString().startsWith(writtenText))
731
                                                        continueInLoop = false; // Because items are sorted in the array 'itemsSearchesShow'
732
                                                else
733
                                                {
734
                                                        this.lowIndex --;
735
                                                        if (this.lowIndex < 0) // Because the item at the 0 position has already been verified
736
                                                                continueInLoop = false;
737
                                                }
738
                                        }
739
                                        this.lowIndex++;
740
                                        
741
                                        // Seek up
742
                                        this.hightIndex ++;
743
                                        if (this.hightIndex < itemsSearchesShow.length)
744
                                                continueInLoop = true;
745
                                        else
746
                                                continueInLoop = false;
747
                                        
748
                                        while (continueInLoop)
749
                                        {
750
                                                if (!itemsSearchesShow[this.hightIndex].toString().startsWith(writtenText)) 
751
                                                        continueInLoop = false; // Because items are sorted in the array 'itemsSearchesShow'
752
                                                else
753
                                                {
754
                                                        this.hightIndex ++;
755
                                                        if (this.hightIndex >= itemsSearchesShow.length) // Because the item at the 0 position has already been verified
756
                                                                continueInLoop = false;
757
                                                }
758
                                        }
759
                                        this.hightIndex --;                                
760
                                }
761
                                else
762
                                {
763
                                        // Seek down
764
                                        this.lowIndex --;
765
                                        if (this.lowIndex > -1)
766
                                                continueInLoop = true;
767
                                        else
768
                                                continueInLoop = false;
769

    
770
                                        while (continueInLoop)
771
                                        {
772
                                                if (!itemsSearchesShow[this.lowIndex].toString().toUpperCase().startsWith(writtenText.toUpperCase()))
773
                                                        continueInLoop = false; // Because items are sorted in the array 'itemsSearchesShow'
774
                                                else
775
                                                {
776
                                                        this.lowIndex --;
777
                                                        if (this.lowIndex < 0) // Because the item at the 0 position has already been verified
778
                                                                continueInLoop = false;
779
                                                }
780
                                        }
781
                                        this.lowIndex++;
782
                                        
783
                                        // Seek up
784
                                        this.hightIndex ++;
785
                                        if (this.hightIndex < itemsSearchesShow.length)
786
                                                continueInLoop = true;
787
                                        else
788
                                                continueInLoop = false;
789
                                        
790
                                        while (continueInLoop)
791
                                        {
792
                                                if (!itemsSearchesShow[this.hightIndex].toString().toUpperCase().startsWith(writtenText.toUpperCase()))
793
                                                        continueInLoop = false; // Because items are sorted in the array 'itemsSearchesShow'
794
                                                else
795
                                                {
796
                                                        this.hightIndex ++;
797
                                                        if (this.hightIndex >= itemsSearchesShow.length) // Because the item at the 0 position has already been verified
798
                                                                continueInLoop = false;
799
                                                }
800
                                        }
801
                                        this.hightIndex --;                                        
802
                                }                                
803
                        }
804
                        logger.debug("Low-Index: " + this.lowIndex + "; Hight-Index: " + this.hightIndex);
805
                        
806
                        
807

    
808
                        // This executed only for cases which isn't enabled case sensitive
809
                        if (!isCaseSensitive_Flag())
810
                        {
811
                                // Second -> if indexes are the same -> search the rank of items (items are ordered in the 'itemsSearchesShow' array
812
                                if (this.lowIndexSubSet2 == this.hightIndexSubSet2)
813
                                {                                
814

    
815
                                        // Seek down
816
                                        this.lowIndexSubSet2 --;
817
                                        if (this.lowIndexSubSet2 > -1)
818
                                                continueInLoop = true;
819
                                        else
820
                                                continueInLoop = false;
821

    
822
                                        while (continueInLoop)
823
                                        {
824
                                                if (!itemsSearchesShow[this.lowIndexSubSet2].toString().toUpperCase().startsWith(writtenText.toUpperCase()))
825
                                                        continueInLoop = false; // Because items are sorted in the array 'itemsSearchesShow'
826
                                                else
827
                                                {
828
                                                        this.lowIndexSubSet2 --;
829
                                                        if (this.lowIndexSubSet2 < 0) // Because the item at the 0 position has already been verified
830
                                                                continueInLoop = false;
831
                                                }
832
                                        }
833
                                        this.lowIndexSubSet2++;
834
                                        
835
                                        // Seek up
836
                                        this.hightIndexSubSet2 ++;
837
                                        if (this.hightIndexSubSet2 < itemsSearchesShow.length)
838
                                                continueInLoop = true;
839
                                        else
840
                                                continueInLoop = false;
841
                                        
842
                                        while (continueInLoop)
843
                                        {
844
                                                if (!itemsSearchesShow[this.hightIndexSubSet2].toString().toUpperCase().startsWith(writtenText.toUpperCase()))
845
                                                        continueInLoop = false; // Because items are sorted in the array 'itemsSearchesShow'
846
                                                else
847
                                                {
848
                                                        this.hightIndexSubSet2 ++;
849
                                                        if (this.hightIndexSubSet2 >= itemsSearchesShow.length) // Because the item at the 0 position has already been verified
850
                                                                continueInLoop = false;
851
                                                }
852
                                        }
853
                                        this.hightIndexSubSet2 --;
854
                                }                                
855
                                
856
                                logger.debug("Low-Index: " + this.lowIndexSubSet2 + "; Hight-Index: " + this.hightIndexSubSet2);
857
                        }
858
                }
859
        
860
                /**
861
                 * Returns the low index of the first rank.
862
                 * 
863
                 * @return Low index value.
864
                 */
865
                public int getLowIndex() {
866
                        return this.lowIndex;
867
                }
868
                
869
                /**
870
                 * Returns the hight index of the first rank.
871
                 * 
872
                 * @return Hight index value
873
                 */
874
                public int getHightIndex() {
875
                        return this.hightIndex;
876
                }
877

    
878
                /**
879
                 * Returns the low index of the second rank. (It's used only when the flag 'case-sensitive' is true.) 
880
                 * 
881
                 * @return Low index value.
882
                 */
883
                public int getLowIndexSecondSubSet() {
884
                        return this.lowIndexSubSet2;
885
                }
886
                
887
                /**
888
                * Returns the hight index of the second rank. (It's used only when the flag 'case-sensitive' is true.) 
889
                * 
890
                * @return Hight index value.
891
                */
892
                public int getHightIndexSecondSubSet() {
893
                        return this.hightIndexSubSet2;
894
                }
895
        }
896
}