Statistics
| Revision:

root / trunk / libraries / libUI / src / org / gvsig / gui / beans / comboBoxItemsSeeker / AbstractDefaultComboBoxItemsSeekerConfigurableModel.java @ 7964

History | View | Annotate | Download (28.9 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.comboBoxItemsSeeker;
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
        /** 
132
         * @see DefaultComboBoxModel#DefaultComboBoxModel()
133
         */
134
        public AbstractDefaultComboBoxItemsSeekerConfigurableModel() {
135
                super();
136
        }
137
        
138
        /** 
139
         * @see DefaultComboBoxModel#DefaultComboBoxModel(Object[])
140
         */
141
        public AbstractDefaultComboBoxItemsSeekerConfigurableModel(Object[] items) {                
142
                super(items);
143
        }
144

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

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

    
192
        /**
193
         * Retuns the start behavior configuration of this model. Configuration values are:
194
     *    + MAINTAIN_ORIGINAL_POSITION_START -> Returns items in the same order as DefaultComboBoxModel (according they were introduced).
195
     *    + ORDERED_START -> Returns items ordered.
196
     *    + DISORDERED_START -> Returns items disordered.
197
         * 
198
         * @return Start-Behavior configuration
199
         */
200
        public int getStartBehavior() {
201
                return this.startBehavior;
202
        }
203
        
204
        /**
205
         * Sets the start behavior configuration for this model. Configuration values are:
206
     *    + MAINTAIN_ORIGINAL_POSITION_START -> Returns items in the same order as DefaultComboBoxModel (according they were introduced).
207
     *    + ORDERED_START -> Returns items ordered.
208
     *    + DISORDERED_START -> Returns items disordered.
209
         * 
210
         * @return Start-Behavior configuration
211
         */
212
        public void setStartBehavior(int start_Behavior) {
213
                this.startBehavior = start_Behavior;                
214
        }
215

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

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

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

    
270
        ////// END METHODS FOR THE BEHAVIOR FLAGS //////
271
        
272

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

    
282
        /*
283
         *  (non-Javadoc)
284
         * @see javax.swing.ListModel#getElementAt(int)
285
         */
286
        public abstract Object getElementAt(int index);
287

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

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

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

    
395
        ////// END USE OF SOME METHODS OF "DefaultComboBoxModel" //////        
396

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

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

    
650
                                // Iterational version of a binary search of the first item that its start matches with a text
651
                                // In this case tries to find a subset of items that ther string value start with uppercase
652
                                while (continueInLoop)
653
                                {
654
                                        // If can't continue searching (item hasn't been found) (With this condition we avoid infinites loops)
655
                                        if (currentIteration > maxNumberOfIterations)
656
                                        {
657
                                                this.lowIndexSubSet2 = this.hightIndexSubSet2 + 1; // Force not show any item after
658
                                                continueInLoop = false;                                                        
659
                                        }
660
                                        else
661
                                        {
662
                                                mediumIndex = (int) Math.floor((this.lowIndexSubSet2 + this.hightIndexSubSet2) / 2);
663
                                                                                        
664
                                                // If has find the first item that mathes its start
665
                                                if (itemsSearchesShow[mediumIndex].toString().toUpperCase().startsWith(writtenText.toUpperCase()))
666
                                                {
667
                                                        this.lowIndexSubSet2 = this.hightIndexSubSet2 = mediumIndex;
668
                                                        continueInLoop = false;
669
                                                }
670
                                                else
671
                                                {
672
                                                        // Reduce the rank of search
673
                                                        if (itemsSearchesShow[mediumIndex].toString().compareTo(writtenText.toUpperCase()) > 0) // da problemas
674
                                                                this.hightIndexSubSet2 = mediumIndex - 1;                                                        
675
                                                        else
676
                                                                this.lowIndexSubSet2 = mediumIndex + 1;
677
                                                        
678
                                                        // If can't continue searching (item hasn't been found)
679
                                                        if (this.lowIndexSubSet2 > this.hightIndexSubSet2)
680
                                                                continueInLoop = false;                                                        
681
                                                        else
682
                                                                currentIteration ++;
683
                                                }
684
                                        }
685
                                }
686
                                
687
                                logger.debug("BINARY-SEARCH-SecondSubSet: Low-Index: " + this.lowIndexSubSet2 + "; Hight-Index: " + this.hightIndexSubSet2);
688
                                
689
                                // Force not do another search of rank of items
690
                                if ((lowIndex == lowIndexSubSet2) && (hightIndex == hightIndexSubSet2))
691
                                        lowIndexSubSet2 = hightIndexSubSet2 + 1;
692
                        }
693
                                        
694
                        
695
                        // Second -> if indexes are the same -> search the rank of items (items are ordered in the 'itemsSearchesShow' array
696
                        if (this.lowIndex == this.hightIndex)
697
                        {                                
698
                                
699
                                if (isCaseSensitive_Flag())
700
                                {
701
                                        // Seek down
702
                                        this.lowIndex --;
703
                                        if (this.lowIndex > -1)
704
                                                continueInLoop = true;
705
                                        else
706
                                                continueInLoop = false;
707

    
708
                                        while (continueInLoop)
709
                                        {
710
                                                if (!itemsSearchesShow[this.lowIndex].toString().startsWith(writtenText))
711
                                                        continueInLoop = false; // Because items are sorted in the array 'itemsSearchesShow'
712
                                                else
713
                                                {
714
                                                        this.lowIndex --;
715
                                                        if (this.lowIndex < 0) // Because the item at the 0 position has already been verified
716
                                                                continueInLoop = false;
717
                                                }
718
                                        }
719
                                        this.lowIndex++;
720
                                        
721
                                        // Seek up
722
                                        this.hightIndex ++;
723
                                        if (this.hightIndex < itemsSearchesShow.length)
724
                                                continueInLoop = true;
725
                                        else
726
                                                continueInLoop = false;
727
                                        
728
                                        while (continueInLoop)
729
                                        {
730
                                                if (!itemsSearchesShow[this.hightIndex].toString().startsWith(writtenText)) 
731
                                                        continueInLoop = false; // Because items are sorted in the array 'itemsSearchesShow'
732
                                                else
733
                                                {
734
                                                        this.hightIndex ++;
735
                                                        if (this.hightIndex >= itemsSearchesShow.length) // Because the item at the 0 position has already been verified
736
                                                                continueInLoop = false;
737
                                                }
738
                                        }
739
                                        this.hightIndex --;                                
740
                                }
741
                                else
742
                                {
743
                                        // Seek down
744
                                        this.lowIndex --;
745
                                        if (this.lowIndex > -1)
746
                                                continueInLoop = true;
747
                                        else
748
                                                continueInLoop = false;
749

    
750
                                        while (continueInLoop)
751
                                        {
752
                                                if (!itemsSearchesShow[this.lowIndex].toString().toUpperCase().startsWith(writtenText.toUpperCase()))
753
                                                        continueInLoop = false; // Because items are sorted in the array 'itemsSearchesShow'
754
                                                else
755
                                                {
756
                                                        this.lowIndex --;
757
                                                        if (this.lowIndex < 0) // Because the item at the 0 position has already been verified
758
                                                                continueInLoop = false;
759
                                                }
760
                                        }
761
                                        this.lowIndex++;
762
                                        
763
                                        // Seek up
764
                                        this.hightIndex ++;
765
                                        if (this.hightIndex < itemsSearchesShow.length)
766
                                                continueInLoop = true;
767
                                        else
768
                                                continueInLoop = false;
769
                                        
770
                                        while (continueInLoop)
771
                                        {
772
                                                if (!itemsSearchesShow[this.hightIndex].toString().toUpperCase().startsWith(writtenText.toUpperCase()))
773
                                                        continueInLoop = false; // Because items are sorted in the array 'itemsSearchesShow'
774
                                                else
775
                                                {
776
                                                        this.hightIndex ++;
777
                                                        if (this.hightIndex >= itemsSearchesShow.length) // Because the item at the 0 position has already been verified
778
                                                                continueInLoop = false;
779
                                                }
780
                                        }
781
                                        this.hightIndex --;                                        
782
                                }                                
783
                        }
784
                        logger.debug("Low-Index: " + this.lowIndex + "; Hight-Index: " + this.hightIndex);
785
                        
786
                        
787

    
788
                        // This executed only for cases which isn't enabled case sensitive
789
                        if (!isCaseSensitive_Flag())
790
                        {
791
                                // Second -> if indexes are the same -> search the rank of items (items are ordered in the 'itemsSearchesShow' array
792
                                if (this.lowIndexSubSet2 == this.hightIndexSubSet2)
793
                                {                                
794

    
795
                                        // Seek down
796
                                        this.lowIndexSubSet2 --;
797
                                        if (this.lowIndexSubSet2 > -1)
798
                                                continueInLoop = true;
799
                                        else
800
                                                continueInLoop = false;
801

    
802
                                        while (continueInLoop)
803
                                        {
804
                                                if (!itemsSearchesShow[this.lowIndexSubSet2].toString().toUpperCase().startsWith(writtenText.toUpperCase()))
805
                                                        continueInLoop = false; // Because items are sorted in the array 'itemsSearchesShow'
806
                                                else
807
                                                {
808
                                                        this.lowIndexSubSet2 --;
809
                                                        if (this.lowIndexSubSet2 < 0) // Because the item at the 0 position has already been verified
810
                                                                continueInLoop = false;
811
                                                }
812
                                        }
813
                                        this.lowIndexSubSet2++;
814
                                        
815
                                        // Seek up
816
                                        this.hightIndexSubSet2 ++;
817
                                        if (this.hightIndexSubSet2 < itemsSearchesShow.length)
818
                                                continueInLoop = true;
819
                                        else
820
                                                continueInLoop = false;
821
                                        
822
                                        while (continueInLoop)
823
                                        {
824
                                                if (!itemsSearchesShow[this.hightIndexSubSet2].toString().toUpperCase().startsWith(writtenText.toUpperCase()))
825
                                                        continueInLoop = false; // Because items are sorted in the array 'itemsSearchesShow'
826
                                                else
827
                                                {
828
                                                        this.hightIndexSubSet2 ++;
829
                                                        if (this.hightIndexSubSet2 >= itemsSearchesShow.length) // Because the item at the 0 position has already been verified
830
                                                                continueInLoop = false;
831
                                                }
832
                                        }
833
                                        this.hightIndexSubSet2 --;
834
                                }                                
835
                                
836
                                logger.debug("Low-Index: " + this.lowIndexSubSet2 + "; Hight-Index: " + this.hightIndexSubSet2);
837
                        }
838
                }
839
        
840
                /**
841
                 * Returns the low index of the first rank.
842
                 * 
843
                 * @return Low index value.
844
                 */
845
                public int getLowIndex() {
846
                        return this.lowIndex;
847
                }
848
                
849
                /**
850
                 * Returns the hight index of the first rank.
851
                 * 
852
                 * @return Hight index value
853
                 */
854
                public int getHightIndex() {
855
                        return this.hightIndex;
856
                }
857

    
858
                /**
859
                 * Returns the low index of the second rank. (It's used only when the flag 'case-sensitive' is true.) 
860
                 * 
861
                 * @return Low index value.
862
                 */
863
                public int getLowIndexSecondSubSet() {
864
                        return this.lowIndexSubSet2;
865
                }
866
                
867
                /**
868
                * Returns the hight index of the second rank. (It's used only when the flag 'case-sensitive' is true.) 
869
                * 
870
                * @return Hight index value.
871
                */
872
                public int getHightIndexSecondSubSet() {
873
                        return this.hightIndexSubSet2;
874
                }
875
        }
876
}