Statistics
| Revision:

svn-gvsig-desktop / tags / v1_0_2_Build_912 / libraries / libUI / src / org / gvsig / gui / beans / comboBoxItemsSeeker / JComboBoxItemsSeekerConfigurable.java @ 11422

History | View | Annotate | Download (81.2 KB)

1
package org.gvsig.gui.beans.comboBoxItemsSeeker;
2

    
3
import java.awt.Color;
4
import java.awt.event.ActionEvent;
5
import java.awt.event.FocusAdapter;
6
import java.awt.event.FocusEvent;
7
import java.awt.event.FocusListener;
8
import java.awt.event.KeyAdapter;
9
import java.awt.event.KeyEvent;
10
import java.awt.event.KeyListener;
11
import java.awt.event.MouseAdapter;
12
import java.awt.event.MouseEvent;
13
import java.awt.event.MouseWheelEvent;
14
import java.awt.event.MouseWheelListener;
15
import java.beans.PropertyChangeEvent;
16
import java.beans.PropertyChangeListener;
17

    
18
import javax.swing.ComboBoxEditor;
19
import javax.swing.ComboBoxModel;
20
import javax.swing.JComboBox;
21
import javax.swing.JOptionPane;
22
import javax.swing.event.CaretListener;
23
import javax.swing.event.DocumentEvent;
24
import javax.swing.event.DocumentListener;
25
import javax.swing.event.ListDataEvent;
26
import javax.swing.event.ListDataListener;
27
import javax.swing.event.PopupMenuEvent;
28
import javax.swing.event.PopupMenuListener;
29
import javax.swing.event.UndoableEditEvent;
30
import javax.swing.event.UndoableEditListener;
31
import javax.swing.text.AttributeSet;
32
import javax.swing.text.BadLocationException;
33
import javax.swing.text.JTextComponent;
34
import javax.swing.text.PlainDocument;
35
import javax.swing.undo.CannotRedoException;
36
import javax.swing.undo.CannotUndoException;
37
import javax.swing.undo.UndoManager;
38

    
39
import org.apache.log4j.Logger;
40
import org.gvsig.gui.beans.Messages;
41
import org.gvsig.gui.beans.optionsEditionByMousePopupMenu.JOptionsEditionByMousePopupMenu;
42

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

    
84
/** ?? EN DESARROLLO !!
85
 * A component that is a modification of JComboBox, of which inherits.
86
 * This component allows:
87
 *    - To show item/s that the start of their string value matches with the text written in the editable field
88
 *    - To be configured it's behavior.
89
 *    
90
 * This component has been done according the MVC (Model-View-Control) pattern, and is a 'Bean'.
91
 *    
92
 * There are 11 configuration flags/attributes: 3 for the Model and the others for the Control and/or View.
93
 *    ? Model flags/attributes (for more information see the 'AbstractDefaultComboBoxItemsSeekerConfigurableModel' class documentation):
94
 *         - Start Behavior -> Configure how return items at beginning (always returns all items).         
95
 *         - Search Behavior -> Configure how return items when it's searching an item.
96
 *         - Case Sensitive -> Discriminates capital letters from small letters or not when seeks items
97
 *    ? Control and/or View flags (all flags can be 'true' or 'false'):
98
 *         - Only One Color On Text:
99
 *                     + true -> always uses black color on text
100
 *              + false -> by default uses black color on text, but if text written by user doesn't match with any item, text will be on red color
101
 *         - Complete Matched Item:
102
 *                     + true -> When user writes, shows also the rest of the current matched item that user hasn't written.
103
 *                      + false -> Only shows the text written by the user when user is writting.
104
 *         - Beep Enabled:
105
 *              + true -> a beep-sound is listened when no item matches with the text written.
106
 *              + false -> no sound is listened.
107
 *         - Allowed Mouse Edition Popup Menu:
108
 *                     + true -> a 'PopupMenu' for text edition that appears when the user clicks on the text-edition-field with the right
109
 *                           button of the mouse.
110
 *              + false -> that 'PopupMenu' won't appear. 
111
 *         - To Force To Only Coincidences In The Search:
112
 *                     + true -> If the user has written some text that doesn't mach with any item, and press the 'Enter' key for close the popup the user will
113
 *                           see written in the text-edition-field the last item which matched with the text written, or the first item of the model if
114
 *                           there wasn't.
115
 *              + false -> If no item matches with the text written and the user presses the 'Enter' key, no item will be selected.
116
 *         - Use Highlight:
117
 *              + true -> marks characters of the text in the text-edition-field with a highlight.
118
 *              + false -> doesn't do that.
119
 *         - Select An Item When Loses Focus:
120
 *              + true -> If user or an application makes component lose its focus, an item will be selected.
121
 *              + false -> If user or an application makes component lose its focus, the component will stay as it was
122
 *    . Control and Model flag (can be 'true' or 'false'):
123
 *         - Allowed Repeated Items -> Uses one of the two models according the value of this flag:
124
 *              + true -> Uses 'ComboBoxItemsSeekerConfigurableModel' as model (this could work slowly).
125
 *              + false -> Uses 'ComboBoxSingularItemsSeekerConfigurableModel' as model.
126
 *
127
 * By default the configuration is:
128
 *     - Start_Behavior = MAINTAIN_ORIGINAL_POSITION_START
129
 *     - Search_Behavior = ORDERED_DYNAMIC_SEARCH
130
 *     - Case_Sensitive = false
131
 *     - Only_One_Color_On_Text = false
132
 *     - Complete_Matched_Item = true
133
 *     - Beep_Enabled = true
134
 *     - Allowed_Repeated_Items = false 
135
 *     - Allowed_Mouse_Edition_Popup_Menu = true
136
 *     - To_Force_To_Only_Coincidences_In_The_Search = true
137
 *     - Use_Highlight = true
138
 *     - Select_An_Item_When_Loses_Focus = false
139
 *     
140
 * Other functionality:
141
 *     - Similar functionality as JComboBox:
142
 *         + Select an item from the inner popup using the mouse
143
 *         + Show item/items that match in the inner popup
144
 *         + Similar edition operations: Right, left, ...
145
 *         + ...
146
 *     - With the keyboard the user can do the same operations as with the "edition popup menu" :
147
 *         CTRL + A -> Select all text
148
 *         CTRL + Z -> Undo
149
 *         CTRL + SHIFT + Z -> Redo
150
 *         CTRL + C -> Copy selected text         
151
 *         CTRL + X -> Cut selected text
152
 *         CTRL + V -> Paste on selected text/position
153
 *         DELETE (SUPR in Spanish Keyboard) -> Remove selected text
154
 *     - ESC key -> Sets the component to its initial state (that user can estimate)
155
 *
156
 * Special-Warning characteristics
157
 *     - In same inherit states the view could don't match with the model (this states aren't final states)
158
 *
159
 * Limitations:
160
 *     - Items of the model of this component must have a "string" value returned by "toString()" method
161
 *     - If the model of the component has lot of items, this could work slowly.
162
 *     - If the model has repeated items -> set true the flag 'allowedRepeatedItems', this will use the 'ComboBoxItemsSeekerConfigurableModel' model,
163
 *         and will work more slowly than the 'ComboBoxSingularItemsSeekerConfigurableModel' model; more as more items had the model.
164
 *     - It's possible that some combination of configuration would be unmanageable.
165
 *     - It's possible that some configuration or some operation fail !!  
166
 *
167
 * @author Pablo Piqueras Bartolom? (p_queras@hotmail.com)
168
 */
169
public class JComboBoxItemsSeekerConfigurable extends JComboBox implements java.io.Serializable {
170
        private static final long serialVersionUID = 6581895116338237598L;
171

    
172
        // CONSTANTS FOR THE CURRENT STATE OF THE COMPONENT
173
        private final int BEGINNING_VIEW_STATE = 0;
174
        private final int START_VIEW_STATE = 1;
175
        private final int SEARCH_VIEW_STATE = 2;
176
        // END CONSTANTS FOR THE CURRENT STATE OF THE COMPONENT        
177
        
178
        // ATTRIBUTE FOR THE CURRENT STATE
179
        private int currentShowState; // 0 -> at the beginning; 1 -> when is showing the start list of items; 2 -> when is showing a search list of items
180
        // END ATTRIBUTE FOR THE CURRENT STATE
181

    
182
        // CONSTANTS FOR CONFIGURE THE BEHAVIOR
183
        public static final boolean DEFAULT_ONLY_ONE_COLOR_ON_TEXT_CONFIGURATION = false;
184
        public static final boolean DEFAULT_COMPLETE_MATCHED_ITEM_CONFIGURATION = true;
185
        public static final boolean DEFAULT_BEEP_ENABLED_CONFIGURATION = true;
186
        public static final boolean DEFAULT_ALLOWED_REPEATED_ITEMS_CONFIGURATION = false;
187
        public static final boolean DEFAULT_ALLOWED_MOUSE_EDITION_POPUP_MENU_CONFIGURATION = true;
188
        public static final boolean DEFAULT_TO_FORCE_TO_ONLY_COINCIDENCES_IN_THE_SEARCH_CONFIGURATION = true;
189
        public static final boolean DEFAULT_USE_HIGHLIGHT_CONFIGURATION = true;
190
        public static final boolean DEFAULT_SELECT_AN_ITEM_WHEN_LOSES_FOCUS_CONFIGURATION = false;
191
        // END CONSTANTS FOR CONFIGURE THE BEHAVIOR
192
        
193
        // CONFIGURATION FLAGS
194
        private boolean onlyOneColorOnText_Flag;
195
        private boolean completeMatchedItem_Flag;
196
        private boolean beepEnabled_Flag;
197
        private boolean allowedRepeatedItems_Flag;
198
        private boolean allowedMouseEditionPopupMenu_Flag;
199
        private boolean toForceToOnlyCoincidencesInTheSearch_Flag;
200
        private boolean useHighlight_Flag;
201
        private boolean selectAnItemWhenLosesFocus_Flag;
202
        // END FLAGS
203
        
204
        // STORE THE SELECTED ITEM AND THE LAST SELECTED ITEM
205
        private Object lastSelectedItemPopupUse; // This is used for only update (refresh) de popup when a different item is selected
206
    // END STORE THE SELECTED ITEM AND THE LAST SELECTED ITEM
207
        
208
        private int num = 0; //sobra -> se usan en el log -> ?? SE PUEDE BORRAR !!
209
        
210
        // NUMBER OF ITEMS SHOWED AT THE SAME TIME IN THE POPUP
211
        private final int POPUP_LIST_ITEMS_HEIGHT = 8;
212
    // END NUMBER OF ITEMS SHOWED AT THE SAME TIME IN THE POPUP
213
        
214
        // MODEL REFERENCE
215
        private AbstractDefaultComboBoxItemsSeekerConfigurableModel model;
216
        // END MODEL REFERENCE
217
        
218
        // LISTENERS
219
        private KeyListener editorKeyListener;
220
        private MouseAdapter editorMouseListener;
221
        private MouseWheelListener editorMouseWheelListener;
222
        private FocusListener editorFocusListener;
223
        private DocumentListener documentListener;
224
        private ListDataListener modelListDataListener;
225
        private PopupMenuListener popupMenuListener;
226
        private PropertyChangeListener editionMenuListener;
227
        private CaretListener caretListener;
228
        // END LISTENERS
229
        
230
        // EDITOR DOCUMENT REFERENCE
231
        private PlainDocumentTextFormatter document;
232
        // END EDITOR DOCUMENT REFERENCE
233
        
234
        // OTHER FLAGS
235
        private boolean allowInsertString;
236
        private boolean lastWasTheBeginningState;
237
        private boolean lastWasPressedAKeyModifier;
238
        private boolean popupWillBeVisible;
239
        private boolean optionsEditorWasVisible;
240
        private boolean selecting;
241
        private boolean hidePopupOnFocusLoss;
242
        private boolean hitBackspace;
243
        private boolean hitBackspaceOnSelection;
244
        private boolean addUndoableEditEvent;
245
        private boolean firstTimeItGainsFocusWithData;
246
        private boolean specialSelectionByUserState; // In this state it's possible that model couldn't match with view (the selected item)
247
        private boolean cutOperationDone;
248
        private boolean itemSelectedByMouse;
249
        // OTHER FLAGS
250
        
251
        // TRACE - DEBUG
252
        private Logger logger = Logger.getLogger(JComboBoxItemsSeekerConfigurable.class.getClass());
253
        // END TRACE - DEBUG
254
        
255
        // A POPUPMENU FOR EDITION OPTIONS
256
        private JOptionsEditionByMousePopupMenu optionsEditionByMouse;
257
    // END A POPUPMENU FOR EDITION OPTIONS
258
        
259
        // UNDO-REDO
260
        private UndoManager undoManager;
261
        private int undoRedoLimitActions;
262
        // END UNDO-REDO        
263
        
264
        /**
265
         * Default Constructor without parameters
266
         */
267
        public JComboBoxItemsSeekerConfigurable() {
268
                // Invokes to the parent class constructor                
269
                super();
270

    
271
                // Create attributes and set initial values
272
                this.initialize();
273
                
274
                // Set the default values of the flags
275
                this.setDefaultBehaviorFlagsConfiguration();
276
                
277
                // Other configuration tasks
278
                this.createDefaultListeners();
279
                this.configure();
280
        }
281
        
282
        /**
283
         * Default Constructor with 3 parameters: for the behavior of the Model
284
         * 
285
         * @param 'start_Behavior' Start behavior of the Model.
286
         * @param 'search_Behavior' Search behavior of the Model.
287
         * @param 'case_Sensitive' Case sensitive behavior of the Model.
288
         */
289
        public JComboBoxItemsSeekerConfigurable(int start_Behavior, int search_Behavior, boolean case_Sensitive)        {
290
                // Invokes to the parent class constructor                
291
                super();
292
                
293
                // Set the default values of the flags
294
                this.setDefaultBehaviorFlagsConfiguration();
295
                
296
                // Create attributes and set initial values
297
                this.initialize();
298
                
299
                // Sets the options selected by the user
300
                this.model.setStartBehavior(start_Behavior);
301
                this.model.setStartBehavior(search_Behavior);
302
                this.model.setCaseSensitive_Flag(case_Sensitive);                
303
                
304
                if (!testFlagsConfigurationOK())
305
                        JOptionPane.showMessageDialog(this, Messages.getText("errorMessageJComboBoxItemsSeekerConfigurable"), Messages.getText("exportJOP2Title"), JOptionPane.ERROR_MESSAGE);
306
                else
307
                {
308
                        // Other configuration tasks
309
                        this.createDefaultListeners();
310
                        this.configure();
311
                }
312
        }
313

    
314
        /**
315
          * Default Constructor with 11 parameters
316
         * 
317
         * @param 'start_Behavior', Start behavior of the Model.
318
         * @param 'search_Behavior', Search behavior of the Model.
319
         * @param 'case_Sensitive', Case sensitive behavior of the Model.
320
         * @param 'only_One_Color_On_Text', Text color, behavior of the Control/View. 
321
         * @param 'complete_Matched_Item', Complete matched item, behavior of the Control/View.
322
         * @param 'use_Beep Use beep', behavior of the Control.
323
         * @param 'allowed_Repeated_Items', Allowed repeated items, behavior of the Control/Model.
324
         * @param 'allowed_Mouse_Edition_Popup_Menu', Allowed mouse edition popupmenu, behavior of the Control/View.
325
         * @param 'to_Force_To_Only_Coincidences_In_The_Search', To force to only coincidences in the search, behavior of the Control/View.
326
         * @param 'use_Highlight', Use highlight behavior of the Control/View.
327
         * @param 'select_An_Item_When_Loses_Focus', behavior of the Control/View
328
         */
329
        public JComboBoxItemsSeekerConfigurable(int start_Behavior, int search_Behavior, boolean case_Sensitive, boolean only_One_Color_On_Text, boolean complete_Matched_Item, boolean use_Beep, boolean allowed_Repeated_Items, boolean allowed_Mouse_Edition_Popup_Menu, boolean to_Force_To_Only_Coincidences_In_The_Search, boolean use_Highlight, boolean select_An_Item_When_Loses_Focus_Flag) {
330
                // Invokes to the parent class constructor                
331
                super();
332
                
333
                this.onlyOneColorOnText_Flag = only_One_Color_On_Text;
334
                this.completeMatchedItem_Flag = complete_Matched_Item;
335
                this.beepEnabled_Flag = use_Beep;
336
                this.allowedRepeatedItems_Flag = allowed_Repeated_Items;
337
                this.allowedMouseEditionPopupMenu_Flag = allowed_Mouse_Edition_Popup_Menu;
338
                this.toForceToOnlyCoincidencesInTheSearch_Flag = to_Force_To_Only_Coincidences_In_The_Search;
339
                this.useHighlight_Flag = use_Highlight;
340
                this.selectAnItemWhenLosesFocus_Flag = select_An_Item_When_Loses_Focus_Flag;
341

    
342
                // Create attributes and set initial values
343
                this.initialize();
344

    
345
                // Sets the options selected by the user
346
                this.model.setStartBehavior(start_Behavior);
347
                this.model.setSearchBehavior(search_Behavior);
348
                this.model.setCaseSensitive_Flag(case_Sensitive);
349
                
350
                if (!testFlagsConfigurationOK())
351
                        JOptionPane.showMessageDialog(this, Messages.getText("errorMessageJComboBoxItemsSeekerConfigurable"), Messages.getText("exportJOP2Title"), JOptionPane.ERROR_MESSAGE);
352
                else
353
                {
354
                        // Other configuration tasks
355
                        this.createDefaultListeners();
356
                        this.configure();
357
                }
358
        }
359

    
360
        /**
361
         *  Sets the default values of the flags
362
         */
363
        private void setDefaultBehaviorFlagsConfiguration() {
364
                this.onlyOneColorOnText_Flag = DEFAULT_ONLY_ONE_COLOR_ON_TEXT_CONFIGURATION;
365
                this.completeMatchedItem_Flag = DEFAULT_COMPLETE_MATCHED_ITEM_CONFIGURATION;
366
                this.beepEnabled_Flag = DEFAULT_BEEP_ENABLED_CONFIGURATION;
367
                this.allowedRepeatedItems_Flag = DEFAULT_ALLOWED_REPEATED_ITEMS_CONFIGURATION;
368
                this.allowedMouseEditionPopupMenu_Flag = DEFAULT_ALLOWED_MOUSE_EDITION_POPUP_MENU_CONFIGURATION;
369
                this.toForceToOnlyCoincidencesInTheSearch_Flag = DEFAULT_TO_FORCE_TO_ONLY_COINCIDENCES_IN_THE_SEARCH_CONFIGURATION;
370
                this.useHighlight_Flag = DEFAULT_USE_HIGHLIGHT_CONFIGURATION;
371
                this.selectAnItemWhenLosesFocus_Flag = DEFAULT_SELECT_AN_ITEM_WHEN_LOSES_FOCUS_CONFIGURATION;
372
        }
373
        
374
        /**
375
         * This method sets the start values of inner attributes and creates the necessary inner objects
376
         */
377
        private void initialize() {
378
                // Attributes for highlight selection
379
                selecting = false;
380
                hitBackspace = false;
381
                
382
                // Creates the model for this component and gets it reference
383
                if (this.allowedRepeatedItems_Flag)
384
                {
385
                        super.setModel(new ComboBoxItemsSeekerConfigurableModel());
386
                        this.model = (ComboBoxItemsSeekerConfigurableModel) super.getModel();
387
                }
388
                else
389
                {
390
                        super.setModel(new ComboBoxSingularItemsSeekerConfigurableModel());
391
                        this.model = (ComboBoxSingularItemsSeekerConfigurableModel) super.getModel();
392
                }
393
                
394
        // Allows user to edit on the combobox
395
                super.setEditable(true);
396
                
397
                // By default the last state of showign items was showing all the items (at the beginning of this component)
398
                currentShowState = BEGINNING_VIEW_STATE;
399
                
400
                // Set the last selected item -> if there isn't any item -> -1; else -> this will be 0
401
                super.setSelectedIndex(-1);
402
                
403
                // By default any text key has been pressed
404
                allowInsertString = false;
405
                
406
                // Attribute for allow composed characters: examples: ?, ?, ?
407
                lastWasPressedAKeyModifier = false;
408
                
409
                // By default popup won't be visible when gained the focus the editor associated
410
                popupWillBeVisible = false;
411
                
412
                // Text options edition popupmenu initialization
413
                optionsEditionByMouse = new JOptionsEditionByMousePopupMenu();
414
                optionsEditorWasVisible = false;
415
                
416
                // Undo-Redo initialization                
417
                addUndoableEditEvent = false; // By default don't add undoable edit events
418
                undoManager = new UndoManager();
419
                undoRedoLimitActions = 10; // By default is 1
420
                undoManager.setLimit(undoRedoLimitActions);
421
                
422
                // By default this flag will be 'true'
423
                firstTimeItGainsFocusWithData = true;
424
                
425
                // By default this component won't be in the "SpecialSelectionByUser" state
426
                specialSelectionByUserState = false;
427
                
428
                // By default no 'cut' operation has been done
429
                cutOperationDone = false;
430
                
431
                // By default no item items has been selected by mouse
432
                itemSelectedByMouse = false;
433
        }
434
        
435
        /**
436
         * Creation of default listeneres that will use the component
437
         */
438
        private void createDefaultListeners() {
439
                // Defines a listener for the PopupMenu of text edition options: when a change is produced in that component, it fires an event
440
                //   and this listener captures it
441
                this.defineEditionMenuPropertyChangeListener(this);
442
                
443
        // Defines a key listener for the editor of this component
444
        this.defineEditorKeyListener(this);
445
         
446
        // Defines a focus listener for the editor of this component
447
        this.defineEditorFocusListener(this);
448
        
449
        // Defines a mouse listener for the editor of this component
450
        this.defineEditorMouseListener(this);
451
        
452
        // Defines a mouse wheel listener for the editor of this component
453
        this.defineEditorMouseWheelListener();
454
        
455
        // Defines a document listener for changes of text
456
        this.defineDocumentListener();
457
         
458
                // Defines a list data listener for the model of this component
459
        this.defineModelListDataListener();
460
        
461
        // Defines a popup menu listener for the popup of this component
462
        this.definePopUpMenuListener();
463
        }
464
        
465

    
466
        /**
467
         * Defines a listener for the PopupMenu of text edition options: when a change is produced in that component, it fires an event
468
         *    and this listener captures and treats it
469
         *    
470
         * @param combo_Box A reference of this component
471
         */
472
        private void defineEditionMenuPropertyChangeListener(JComboBoxItemsSeekerConfigurable combo_Box) {
473
                final JComboBoxItemsSeekerConfigurable comboBoxReference = combo_Box;
474
                
475
                editionMenuListener = new PropertyChangeListener() {
476
                        /*
477
                         * (non-Javadoc)
478
                         * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)
479
                         */
480
                        public void propertyChange(PropertyChangeEvent arg0) {
481
                                if (arg0.getPropertyName().equals(JOptionsEditionByMousePopupMenu.SELECTEDOPTION)) {
482
                            JTextComponent editor = (JTextComponent) comboBoxReference.getEditor().getEditorComponent();
483
                
484
                            logger.debug("PropertyChanged: " + arg0.getNewValue().toString());
485
                                        
486
                                  switch(Integer.parseInt(arg0.getNewValue().toString()))
487
                                  {
488
                                          case JOptionsEditionByMousePopupMenu.UNDO:
489
                                                  undoOperationLogic();
490
                                                  break;
491
                                          case JOptionsEditionByMousePopupMenu.REDO:
492
                                                  redoOperationLogic();
493
                                                  break;
494
                                          case JOptionsEditionByMousePopupMenu.CUT:
495
                                                  editor.cut();
496
                                                  cutOperationDone = true;
497
                                                  deleteTextLogic(editor, false);
498
                                                  break;
499
                                          case JOptionsEditionByMousePopupMenu.COPY:
500
                                                  editor.copy();
501
                                                  break;
502
                                          case JOptionsEditionByMousePopupMenu.PASTE:
503
                                                  editor.paste();
504
                                                  
505
                                                  try {
506
                                                          String newPattern = document.getText(0, document.getLength());
507
                                                          model.setWrittenText(newPattern);
508
                                                          updatePopUpView();
509
                                                  } catch (BadLocationException e) {
510
                                                          e.printStackTrace();
511
                                                  }
512
                                                  break;
513
                                          case JOptionsEditionByMousePopupMenu.DELETE:
514
                                                  deleteTextLogic(editor, false);
515
                                                  break;
516
                                          case JOptionsEditionByMousePopupMenu.SELECT_ALL:
517
                                                  editor.selectAll();
518
                                                  break;
519
                                          default: // do anything
520
                                  }
521
                                }
522
                                else
523
                                {
524
                                        if (arg0.getPropertyName().equals(JOptionsEditionByMousePopupMenu.VISIBILITYCHANGED))
525
                                        {
526
                                                logger.debug("PropertyChanged: " + arg0.getNewValue().toString());
527
                                                
528
                                                // First True, after False (when false -> optionsEditorWasVisible = true)
529
                                                if (!optionsEditionByMouse.isVisible())
530
                                                        optionsEditorWasVisible = true;
531
                                                else
532
                                                        optionsEditorWasVisible = false;
533
                                        }
534
                                }
535
                        }                        
536
                };
537
        }        
538
        
539
        /**
540
         *  Defines a document listener for changes of text
541
         */
542
        private void defineDocumentListener() {
543
       documentListener = new DocumentListener() {
544
               /*
545
                * (non-Javadoc)
546
                * @see javax.swing.event.DocumentListener#changedUpdate(javax.swing.event.DocumentEvent)
547
                */
548
               public void changedUpdate(DocumentEvent arg0) {
549
               }
550

    
551
               /*
552
                * (non-Javadoc)
553
                * @see javax.swing.event.DocumentListener#insertUpdate(javax.swing.event.DocumentEvent)
554
                */
555
               public void insertUpdate(DocumentEvent arg0) {
556
                       logger.debug("NUM: " + num + " DocumentListener->insertUpdate");
557
                       num++;                                
558
                                
559
                       // Indicate to the model that now is disabled the start view
560
                       // This is used for the first text inserted to the document when the component is loaded and it does setSelectedIndex(0), to avoid use a search view
561
                       if (currentShowState == BEGINNING_VIEW_STATE)
562
                       {
563
                               currentShowState = START_VIEW_STATE;
564
                               lastWasTheBeginningState = true;
565
                               logger.debug("Pasa al estado 1 (de vista inicial)");
566
                       }        
567
               }
568

    
569
               /*
570
                * (non-Javadoc)
571
                * @see javax.swing.event.DocumentListener#removeUpdate(javax.swing.event.DocumentEvent)
572
                */
573
               public void removeUpdate(DocumentEvent arg0) {
574
                       logger.debug("NUM: " + num + " DocumentListener->removeUpdate");
575
                       num++;
576
               }                        
577
       };
578
        }        
579
        
580
        /**
581
         * Defines a list data listener for the model of this component
582
         */
583
        private void defineModelListDataListener() {                
584
                this.modelListDataListener = new ListDataListener()        {
585
                        /*
586
                         * (non-Javadoc)
587
                         * @see javax.swing.event.ListDataListener#contentsChanged(javax.swing.event.ListDataEvent)
588
                         */
589
                        public void contentsChanged(ListDataEvent e) {
590
                                // This flag indicates to the 'insertString' and 'remove' methods of the PlainDocumentSeeker that the text of the item selected or written by the user
591
                                //  hasn't been written on the TextEditor of ths component
592
                                selecting = false;
593
                        }
594

    
595
                        /*
596
                         * (non-Javadoc)
597
                         * @see javax.swing.event.ListDataListener#intervalAdded(javax.swing.event.ListDataEvent)
598
                         */
599
                        public void intervalAdded(ListDataEvent e) {
600
                        }
601

    
602
                        /*
603
                         * (non-Javadoc)
604
                         * @see javax.swing.event.ListDataListener#intervalRemoved(javax.swing.event.ListDataEvent)
605
                         */
606
                        public void intervalRemoved(ListDataEvent e) {
607
                        }                        
608
                };
609
    }
610

    
611
        /**
612
         * Defines and add a property change listener for this component (AT MOMENT NOT USED!!)
613
         */
614
        private void defineAndAddPropertyChangeListener() {
615
                // Define and add a Listener for changes on the editor or the model of the JComboBox
616
        super.addPropertyChangeListener(new PropertyChangeListener() {
617
            public void propertyChange(PropertyChangeEvent ev) {
618
                if (ev.getPropertyName().equals("editor"))
619
                        configureEditor((ComboBoxEditor) ev.getNewValue());
620
                if (ev.getPropertyName().equals("model"))
621
                {
622
                        if (isAllowedRepeatedItems_Flag())
623
                                model = (ComboBoxItemsSeekerConfigurableModel) ev.getNewValue();
624
                        else
625
                                model = (ComboBoxSingularItemsSeekerConfigurableModel) ev.getNewValue();
626
                }
627
            }
628
        });
629
        }
630

    
631
        /**
632
         * Defines a focus listener for the editor of this component
633
         * 
634
         * @param combo_Box A reference of this component
635
         */
636
        private void defineEditorFocusListener(JComboBoxItemsSeekerConfigurable combo_Box) {
637
                final JComboBoxItemsSeekerConfigurable comboBoxReference = combo_Box;
638
                
639
                // Bug 5100422 on Java 1.5: Editable JComboBox won't hide popup when tabbing out                
640
                hidePopupOnFocusLoss=System.getProperty("java.version").startsWith("1.5");
641

    
642
                // Highlight whole text when gaining focus
643
                editorFocusListener = new FocusAdapter() {
644
                        /*
645
                         * (non-Javadoc)
646
                         * @see java.awt.event.FocusAdapter#focusGained(java.awt.event.FocusEvent)
647
                         */
648
                        public void focusGained(FocusEvent e) {
649
                                if (!optionsEditorWasVisible)
650
                                {
651
                                        logger.debug("currentShowState: " + currentShowState);
652
                                        logger.debug("EDITOR FOCUS GAINED");
653
                                        
654
                                        // This is used for set the text value of the first item added highlighted the first time the component gets the focus 
655
                                        if (firstTimeItGainsFocusWithData) {
656
                                                if (model.getSize() > 0) {
657
                                                        if (useHighlight_Flag)
658
                                                                document.highlightCompletedText(0);
659
                                                        firstTimeItGainsFocusWithData = false;
660
                                                }
661
                                        }
662
                                        
663
                                        // This is used when the component has lost the focus, the popup was in show state and is restored the focus -> update the popup
664
                                        if (popupWillBeVisible)
665
                                        {
666
                                                logger.debug("UPDATE POPUP DESDE EL FOCUSGAINED");
667
                                                comboBoxReference.updatePopUpView();
668
                                        }
669
                                }
670
                        }
671
                        
672
                        /*
673
                         * (non-Javadoc)
674
                         * @see java.awt.event.FocusAdapter#focusLost(java.awt.event.FocusEvent)
675
                         */
676
                        public void focusLost(FocusEvent e) {
677
                                logger.debug("EDITOR FOCUS LOST");
678
                                
679
                                // If it has to select an item always it loses its focus:
680
                                if (selectAnItemWhenLosesFocus_Flag) {
681
                                        // Similar code as the ENTER key code
682
                                        if (getSelectedItem() == null)
683
                                                logger.debug("SELECTED ITEM: NULL");
684
                                        else
685
                                                logger.debug("SELECTED ITEM: " + getSelectedItem().toString());
686

    
687
                                        try {
688
                                                String newText = "";
689
                                                
690
                                                Object moreSimilarItemToLastWrittenText = model.getMoreSimilarItemToLastWrittenText();
691

    
692
                                                // If the last item selected was null -> select the first
693
                                                if (moreSimilarItemToLastWrittenText == null) {
694
                                                        setSelectedItem(model.getParentElementAt(0));
695
                                                }
696
                                                else {
697
                                                        if (specialSelectionByUserState) {
698
                                                                setSelectedItem(model.getSelectedItem());
699
                                                        }
700
                                                        else {
701
                                                                // Else -> select the last
702
                                                                setSelectedItem(moreSimilarItemToLastWrittenText);
703
                                                        }
704
                                                }
705
                                                
706
                                                newText = getSelectedItem().toString();
707
                                                
708
                                                // Reports about the written text to the model
709
                                            if (model.isDynamicSearch())
710
                                                    model.setWrittenText(newText);                                                            
711
                                                
712
                                                specialSelectionByUserState = false;
713
                                                
714
                                                document.replace(0, document.getLength(), newText, null);
715
                                        }
716
                                        catch (BadLocationException e1) {
717
                                            e1.printStackTrace();
718
                                    }
719
                                        
720
//                                    // Indicate to the model that now is disabled the start view
721
//                                        if (currentShowState == START_VIEW_STATE)
722
//                                        {
723
//                                                model.setStartStateFlag(false);
724
//                                                currentShowState = SEARCH_VIEW_STATE;
725
//                                        }
726
                                        hidePopup();
727
                                        
728
                                        // Sets the caret position of the text in the document to the end:                                        
729
                                        ((JTextComponent) comboBoxReference.getEditor().getEditorComponent()).setCaretPosition(document.getLength());                                        
730
                                }
731
                                else { // Else -> Default bevabior
732
                                        if (isPopupVisible())
733
                                                popupWillBeVisible = true;
734
                                        else
735
                                                popupWillBeVisible = false;
736
                                }
737
                                
738
                                // Workaround for Bug 5100422 - Hide Popup on focus loss
739
                                if (hidePopupOnFocusLoss)
740
                                        comboBoxReference.setPopupVisible(false);
741
                        }
742
                };
743
        }
744

    
745
        /**
746
         * Defines a mouse listener for the editor of this component
747
         * 
748
         * @param combo_Box A reference of this component
749
         */
750
        private void defineEditorMouseListener(JComboBoxItemsSeekerConfigurable combo_Box) {
751
                final JComboBoxItemsSeekerConfigurable comboBoxReference = combo_Box;
752
                
753
                editorMouseListener = new MouseAdapter() {
754
                        /*
755
                         * (non-Javadoc)
756
                         * @see java.awt.event.MouseAdapter#mouseClicked(java.awt.event.MouseEvent)
757
                         */
758
                        public void mouseClicked(MouseEvent e) {
759
                                logger.debug("MOUSE-LISTENER : MOUSE-mouseClicked!" + e.getButton());
760
                                logger.debug("MOUSE-LISTENER : MOUSE-mouseClicked!" +e.isPopupTrigger());
761
        
762
                                if (e.getButton() == MouseEvent.BUTTON3) {
763
                            JTextComponent editor = (JTextComponent) comboBoxReference.getEditor().getEditorComponent();
764
                            
765
                            // By default disable all options
766
                            optionsEditionByMouse.setEnabledAllOptions(false);
767
                            
768
                            // Enable the "Undo" option if there is any previous state to restore
769
                            if (undoManager.canUndo())
770
                                    optionsEditionByMouse.setEnabledUndoOption(true);
771
                            
772
                            // Enable the "Redo" option if there is any later state to restore
773
                            if (undoManager.canRedo())
774
                                    optionsEditionByMouse.setEnabledRedoOption(true);
775
                            
776
                            // Enable the "Copy", "Cut" and "Delete" options if there is text selected
777
                            if (editor.getCaretPosition() != editor.getCaret().getMark())
778
                            {
779
                                    optionsEditionByMouse.setEnabledCopyOption(true);
780
                                    optionsEditionByMouse.setEnabledCutOption(true);
781
                                    optionsEditionByMouse.setEnabledDeleteOption(true);
782
                            }
783
                            
784
                            // Enable the "Paste" option if there is text on the system's clipboard
785
                            if ( getToolkit().getSystemClipboard().getContents(this).toString().length() > 0 )
786
                                    optionsEditionByMouse.setEnabledPasteOption(true);
787
                            
788
                            // Enable the "Select-All" option (by default it's always enabled)
789
                            optionsEditionByMouse.setEnabledSelectAllOption(true);
790
                            
791
                                        optionsEditionByMouse.setLocation((int)comboBoxReference.getLocationOnScreen().getX() + e.getX(), (int)comboBoxReference.getLocationOnScreen().getY() + e.getY());
792
                            optionsEditionByMouse.setInvoker(comboBoxReference);
793
                            optionsEditionByMouse.setVisible(true);
794
                    }
795
                }
796
                };
797
        }
798

    
799
        /**
800
         * Defines a mouse wheel listener for the editor of this component
801
         */
802
        private void defineEditorMouseWheelListener() {
803
                editorMouseWheelListener = new MouseWheelListener() {
804
                        /*
805
                         * (non-Javadoc)
806
                         * @see java.awt.event.MouseWheelListener#mouseWheelMoved(java.awt.event.MouseWheelEvent)
807
                         */
808
                        public void mouseWheelMoved(MouseWheelEvent e) {
809
                                specialSelectionByUserState = true;
810
                                
811
                        if (e.getWheelRotation() < 0)
812
                                selectItemUp();
813
                        else
814
                                selectItemDown();
815
                        }
816
                };
817
        }
818

    
819
        /**
820
         * Defines a key listener for the editor of this component
821
         * This method is another important difference from the JComboBox; and could work badly with some keymaps
822
         * 
823
         * @param combo_Box A reference of this component
824
         */
825
        private void defineEditorKeyListener(JComboBoxItemsSeekerConfigurable combo_Box) {
826
                final JComboBoxItemsSeekerConfigurable comboBoxReference = combo_Box;
827
                
828
                editorKeyListener = new KeyAdapter() {
829
                        /*
830
                         * (non-Javadoc)
831
                         * @see java.awt.event.KeyAdapter#keyPressed(java.awt.event.KeyEvent)
832
                         */
833
                        public void keyPressed(KeyEvent ke)  // Executed on the Start view state or Search view state
834
                        {
835
                                logger.debug("Tecla apretada: ->" + ke.getKeyChar() + "<- ; Su keyCode es: " + ke.getKeyCode() + " TIPO: " + Character.getType(ke.getKeyChar()));
836
                                
837
                                if (model.getParentSize() == 0)
838
                                {
839
                                        if (beepEnabled_Flag)
840
                                                comboBoxReference.getToolkit().beep(); // when available use: UIManager.getLookAndFeel().provideErrorFeedback(comboBox);
841
                                }
842
                                else
843
                                {                                                                
844
                                        // This flag indicates to the 'insertString' and 'remove' methods of the PlainDocumentSeeker that the text of the item selected or written by the user
845
                                        //  hasn't been written on the TextEditor of ths component
846
                                        selecting = false;
847
                                        
848
                                        // This resolves the bug when the popup wasn't seen any time and the uses press a key that updates the view of the popup (the bug is that popup has the items but
849
                                        //  aren't seen
850
                                        if (lastWasTheBeginningState)
851
                                        {
852
                                                // This maintains visible the popup
853
                                                if (comboBoxReference.isDisplayable())
854
                                                        comboBoxReference.setPopupVisible(true);
855
                                                lastWasTheBeginningState = false;
856
                                        }
857
                                        
858
                                        if (Character.isLetterOrDigit(ke.getKeyChar())) {
859
                                                logger.debug("IS LETTER OR DIGIT");
860
                                        }
861
                                        else
862
                                                logger.debug("ISN'T LETTER OR DIGIT");
863
                                        
864
                                        JTextComponent editor = (JTextComponent) comboBoxReference.getEditor().getEditorComponent();
865
                                        
866
                                        // COPY, CUT, PASTE, SELECT ALL, UNDO AND REDO WITH THE KEYBOARD (Combination of keys; REMOVE is implemented after: KV_DELETE (supr spanish key))
867
                                        if (ke.isControlDown())
868
                                        {
869
                                                // COPY
870
                                            if (ke.getKeyCode() == KeyEvent.VK_C) {
871
                                                editor.copy();
872
                                                    return;
873
                                            }
874
                                            
875
                                            // CUT
876
                                            if (ke.getKeyCode() == KeyEvent.VK_X) {
877
                                                      editor.cut();
878
                                                      
879
                                                  cutOperationDone = true;
880
                                                  deleteTextLogic(editor, false);                                                
881
                                                    return;
882
                                            }
883
                                            
884
                                            // PASTE
885
                                            if (ke.getKeyCode() == KeyEvent.VK_V) {
886
                                                    editor.paste();
887
                                          
888
                                          try {
889
                                                  String newPattern = document.getText(0, document.getLength());
890
                                                  model.setWrittenText(newPattern);
891
                                                  updatePopUpView();
892
                                          } catch (BadLocationException e) {
893
                                                  e.printStackTrace();
894
                                          }
895
                                                    return;
896
                                            }
897
                                            
898
                                            // SELECT ALL
899
                                            if (ke.getKeyCode() == KeyEvent.VK_A) {
900
                                                    editor.selectAll();
901
                                                    return;
902
                                            }
903

    
904
                                            // UNDO OR REDO
905
                                            if (ke.getKeyCode() == KeyEvent.VK_Z) {
906
                                                    if (ke.isShiftDown()) // REDO
907
                                                            redoOperationLogic();                                                            
908
                                                    else //UNDO
909
                                                            undoOperationLogic();
910
                                                    
911
                                                    return;
912
                                             }
913
                                        }
914
                                        
915
                                        // According the key pressed, do some actions or others
916
                                        switch (ke.getKeyCode())
917
                                        {
918
                                                // determine if the pressed key is backspace (needed by the remove method)
919
                                                case KeyEvent.VK_BACK_SPACE :
920
                                                                 if (useHighlight_Flag)
921
                                                                {
922
                                                                         hitBackspace = true;
923
                                                                         hitBackspaceOnSelection=editor.getSelectionStart()!=editor.getSelectionEnd();
924
                                                                }
925
                                                                 else
926
                                                                         deleteTextLogic(editor, true);
927
                                                        break;
928
                                                        
929
                                                case KeyEvent.VK_DELETE : // 'supr' key in spanish keyboard
930
                                                                specialSelectionByUserState = true;
931
                                                        
932
                                                        deleteTextLogic(editor, false);
933
                                                        break;
934
                                                        
935
                                                case KeyEvent.VK_ENTER :
936
                                                        logger.debug("ENTRA EN EL C?DIGO DE ENTER");
937
        
938
                                                        if (getSelectedItem() == null)
939
                                                                logger.debug("SELECTED ITEM: NULL");
940
                                                        else
941
                                                                logger.debug("SELECTED ITEM: " + getSelectedItem().toString());
942

    
943
                                                        try {
944
                                                                String newText = "";
945
                                                                
946
                                                                Object moreSimilarItemToLastWrittenText = model.getMoreSimilarItemToLastWrittenText();
947

    
948
                                                                // If the last item selected was null -> select the first
949
                                                                if (moreSimilarItemToLastWrittenText == null) {
950
                                                                        setSelectedItem(model.getParentElementAt(0));
951
                                                                }
952
                                                                else {
953
                                                                        if (specialSelectionByUserState) {
954
                                                                                setSelectedItem(model.getSelectedItem());
955
                                                                        }
956
                                                                        else {
957
                                                                                // Else -> select the last
958
                                                                                setSelectedItem(moreSimilarItemToLastWrittenText);
959
                                                                        }
960
                                                                }
961
                                                                
962
                                                                newText = getSelectedItem().toString();
963
                                                                
964
                                                                // Reports about the written text to the model
965
                                                            if (model.isDynamicSearch())
966
                                                                    model.setWrittenText(newText);                                                            
967
                                                                
968
                                                                specialSelectionByUserState = false;
969
                                                                
970
                                                                document.replace(0, document.getLength(), newText, null);
971
                                                        }
972
                                                        catch (BadLocationException e1) {
973
                                                            e1.printStackTrace();
974
                                                    }
975
                                                        
976
                                                    // Indicate to the model that now is disabled the start view
977
                                                        if (currentShowState == START_VIEW_STATE)
978
                                                        {
979
                                                                model.setStartStateFlag(false);
980
                                                                currentShowState = SEARCH_VIEW_STATE;
981
                                                        }
982
                                                        hidePopup();
983
                                                        
984
                                                        // Sets the caret position of the text in the document to the end:
985
                                                        editor.setCaretPosition(document.getLength());
986
                                                        break;
987
                                                        
988
                                                case KeyEvent.VK_DOWN :                                                                
989
                                                        selectItemDown();
990
                                                        showPopup();
991
                                                        break;
992
                                                        
993
                                                case KeyEvent.VK_UP :
994
                                                        selectItemUp();
995
                                                        showPopup();
996
                                                        break;
997
                                                        
998
                                                case KeyEvent.VK_LEFT :                                                
999
                                                        // Move the caret to left
1000
                                                        int caretPosition = editor.getCaretPosition();
1001
                                                        if (caretPosition > 0)
1002
                                                        {
1003
                                                                if (useHighlight_Flag) {
1004
                                                                        editor.setCaretPosition(document.getLength());
1005
                                                                        editor.moveCaretPosition(caretPosition - 1);
1006
                                                                }
1007
                                                                else
1008
                                                                        editor.setCaretPosition(caretPosition - 1);
1009
                                                        }
1010
                                                        else
1011
                                                        {
1012
                                                // User hit backspace with the cursor positioned on the start => beep
1013
                                                    if (beepEnabled_Flag)
1014
                                                            getToolkit().beep(); // when available use: UIManager.getLookAndFeel().provideErrorFeedback(comboBox);
1015
                                                        }
1016
                                                        
1017
                                                        break;
1018
                                                        
1019
                                                case  KeyEvent.VK_RIGHT :
1020
                                                        // Move the caret to right
1021
                                                        caretPosition = editor.getCaretPosition();
1022
                                                        if (caretPosition < document.getLength()) {
1023
                                                                if (useHighlight_Flag) {
1024
                                                                        editor.setCaretPosition(document.getLength());
1025
                                                                        editor.moveCaretPosition(caretPosition + 1);
1026
                                                                }
1027
                                                                else
1028
                                                                        editor.setCaretPosition(caretPosition + 1);
1029
                                                        }
1030
                                                        else
1031
                                                        {
1032
                                                            // User hit backspace with the cursor positioned on the start => beep
1033
                                                                if (beepEnabled_Flag)
1034
                                                                        getToolkit().beep(); // when available use: UIManager.getLookAndFeel().provideErrorFeedback(comboBox);
1035
                                                        }
1036
                                                        
1037
                                                        break;
1038
                                                        
1039
                                                case  KeyEvent.VK_PAGE_DOWN :
1040
                                                        if (getItemCount() > 0)
1041
                                                        {                                                                
1042
                                                                int index;
1043
                                                                specialSelectionByUserState = true;                                                                
1044
                                                                
1045
                                                                if (getSelectedIndex() == -1)
1046
                                                                        index = 0;
1047
                                                                else
1048
                                                                        index = getSelectedIndex() + POPUP_LIST_ITEMS_HEIGHT;
1049
                                                                
1050
                                                                if (index < getItemCount())
1051
                                                                        setSelectedIndex(index);
1052
                                                                else
1053
                                                                        setSelectedIndex(getItemCount()-1);
1054
                                                        }
1055
                                                        break;
1056
                                                        
1057
                                                case KeyEvent.VK_PAGE_UP :
1058
                                                        if (getItemCount() > 0)
1059
                                                        {
1060
                                                                int index;
1061
                                                                specialSelectionByUserState = true;
1062
                                                                
1063
                                                                if (getSelectedIndex() == -1)
1064
                                                                        index = getItemCount() - 1;
1065
                                                                else
1066
                                                                        index = getSelectedIndex() - POPUP_LIST_ITEMS_HEIGHT;
1067
                                                                
1068
                                                                if (index > -1)
1069
                                                                        setSelectedIndex(index);
1070
                                                                else
1071
                                                                        setSelectedIndex(0);
1072
                                                        }
1073
                                                        break;
1074
                                                        
1075
                                                case KeyEvent.VK_HOME : // 'Inicio' key on the spanish keyboard
1076
                                                        editor.setCaretPosition(0);
1077
                                                        break;
1078
                                                        
1079
                                                case KeyEvent.VK_END :  // 'Fin' key on the spanish keyboard
1080
                                                        editor.setCaretPosition(document.getLength());
1081
                                                        break;
1082
                                                        
1083
                                                case KeyEvent.VK_TAB :
1084
                                                        // This avoids that popup listener could report about it detected item
1085
                                                        allowInsertString = true;
1086
                                                        
1087
                                                        if (model.getParentSize() > 0)
1088
                                                        {                                                                
1089
                                                                Object selectedItem;
1090
                                                                
1091
                                                                if (specialSelectionByUserState)
1092
                                                                        selectedItem = getSelectedItem();
1093
                                                                else
1094
                                                                        selectedItem = model.getParentElementAt(0);
1095
                                                                
1096
                                                                String selectedItemName = "";
1097
                                                                
1098
                                                                try {
1099
                                                                        
1100
                                                                        if (selectedItem == null)
1101
                                                                                selectedItemName = model.getFirstItemAdded().toString();
1102
                                                                        else
1103
                                                                                selectedItemName = selectedItem.toString();
1104
                                                                                
1105
                                                                                document.replace(0, document.getLength(), selectedItemName, null);
1106
                                                                } catch (BadLocationException e) {
1107
                                                                        e.printStackTrace();
1108
                                                                }
1109
                                                                
1110
                                                                if (model.isDynamicSearch()) {
1111
                                                                        model.setWrittenText(selectedItemName);
1112
                                                                        logger.debug("Texto que se le env?a al modelo: ->" + selectedItemName + "<-");
1113
                                                                }                
1114
                                                                                
1115
                                                                if (currentShowState == START_VIEW_STATE)
1116
                                                                {
1117
                                                                        model.setStartStateFlag(false);
1118
                                                                        currentShowState = SEARCH_VIEW_STATE;
1119
                                                                }
1120
                                                                
1121
                                                                // It's supposed that the text on the document is equal as the string value of the selected item -> then text must be on black color
1122
                                                                comboBoxReference.getEditor().getEditorComponent().setForeground(Color.BLACK);
1123

    
1124
                                                                updatePopUpView();
1125
                                                        }
1126
                                                        break;
1127
                                                        
1128
                                                case KeyEvent.VK_ESCAPE :
1129
                                                        specialSelectionByUserState = false;
1130
                                                        
1131
                                                        // Force update the popup
1132
                                                        if (isPopupVisible())
1133
                                                                hidePopup();
1134
        
1135
                                                        model.setWrittenText("");
1136
                                                        
1137
                                                        if (currentShowState == SEARCH_VIEW_STATE)
1138
                                                        {        
1139
                                                                try {
1140
                                                                        document.remove(0, document.getLength());
1141
                                                                } catch (BadLocationException e) {
1142
                                                                        e.printStackTrace();
1143
                                                                }
1144
                                                                
1145
                                                                // Return to the start view state
1146
                                                                model.setStartStateFlag(true);
1147
                                                                currentShowState = START_VIEW_STATE;
1148

    
1149
                                                                // Select the first Item
1150
                                                                setSelectedIndex(0);
1151
                                                                
1152
                                                                if (useHighlight_Flag)
1153
                                                                        document.highlightCompletedText(0);
1154
                                                        }
1155
                                                        else
1156
                                                        {
1157
                                                                // Select the first Item
1158
                                                                setSelectedIndex(0);
1159
                                                                
1160
                                                                if (useHighlight_Flag)
1161
                                                                        document.highlightCompletedText(0);
1162
                                                        }
1163
                                                        updatePopUpView();                                                        
1164
                                                        break;
1165
                                                        
1166
                                                case KeyEvent.VK_SHIFT : // Do nothing
1167
                                                        break;
1168
                                                        
1169
                                                case KeyEvent.VK_ALT_GRAPH : // Do nothing
1170
                                                        break;
1171
                                                        
1172
                                                case KeyEvent.VK_ALT : // Do nothing                        
1173
                                                        break;
1174
                                                        
1175
                                                case KeyEvent.VK_CONTROL : // Do nothing
1176
                                                        break;
1177
                                                        
1178
                                                case KeyEvent.VK_NUM_LOCK : // Do nothing
1179
                                                        break;
1180
                                                        
1181
                                                case KeyEvent.VK_CAPS_LOCK : // Do nothing
1182
                                                        break;
1183
                                                        
1184
                                                default:
1185
                                                        logger.debug("Actualiza view flag a false");
1186
                                                                                                
1187
                                                        logger.debug("LASTITEM1 :" + lastSelectedItemPopupUse);
1188
        
1189
                                                        logger.debug("GETMARK: " + editor.getCaret().getMark() + "GETCARETPOSITION" + editor.getCaretPosition());
1190

    
1191
                                                        specialSelectionByUserState = false;
1192
                                                        
1193
                                                        // If it has been pressed a modifier key (Examples: ^ ` ? ?), not consume the key pressed
1194
                                                        if ((Character.getType(ke.getKeyChar()) == Character.MODIFIER_LETTER) || (Character.getType(ke.getKeyChar()) == Character.MODIFIER_SYMBOL))
1195
                                                        {
1196
                                                                logger.debug("CAR?CTER MODIFICADOR");
1197
                                                                lastWasPressedAKeyModifier = true;
1198
                                                        }
1199
                                                        else
1200
                                                        {
1201
                                                                logger.debug("CAR?CTER NO MODIFICADOR");
1202
                                                                allowInsertString = true;
1203

    
1204
                                                        if (lastWasPressedAKeyModifier)
1205
                                                        {
1206
                                                                logger.debug("PRESSED: " + editor.getText().substring(0));
1207
                                                                lastWasPressedAKeyModifier = false;
1208
                                                        }
1209
                                                        
1210
                                                        if (model.isDynamicSearch())
1211
                                                        {
1212
                                                                
1213
                                                                String text;
1214
                                                                if (editor.getCaretPosition() == editor.getCaret().getMark())
1215
                                                                        text = editor.getText().substring(0, editor.getCaretPosition()) + ke.getKeyChar() + editor.getText().substring(editor.getCaretPosition(), editor.getText().length());
1216
                                                                else
1217
                                                                {
1218
                                                                        text = "" + editor.getText().substring(0, (int) Math.min(editor.getCaretPosition(), editor.getCaret().getMark())) + ke.getKeyChar();
1219
                                                                        text += editor.getText().substring((int) Math.max(editor.getCaretPosition(), editor.getCaret().getMark()), editor.getText().length());
1220
                                                                }
1221
                                                                
1222
                                                                    // Reports about the written text to the model                                                
1223
                                                                           logger.debug("Texto que se le env?a KEY al modelo: ->" + text + "<-");
1224
                                                                    model.setWrittenText(text);        
1225
                                                                    
1226
                                                                    // Indicate to the model that now is disabled the start view
1227
                                                                    if (currentShowState == START_VIEW_STATE)
1228
                                                                    {
1229
                                                                            model.setStartStateFlag(false);
1230
                                                                            currentShowState = SEARCH_VIEW_STATE;
1231
                                                                    }
1232
                                                                    
1233
                                                        }
1234
        
1235
                                                updatePopUpView();
1236
                                                        
1237
                                                        logger.debug("Key Pressed:" + ke.getKeyCode());
1238
                                                }
1239
                                        }
1240
                                        
1241
                                        // Consume the key event for not to use the handler of the keyboard of other components
1242
                                        // Only if it has been pressed a modifier key, not consume the key pressed
1243
                                        if (!lastWasPressedAKeyModifier)
1244
                                                ke.consume();
1245
                    }
1246
                        }
1247
                };
1248
        }
1249
        
1250
        /**
1251
         * Defines a popup menu listener for the popup of this component
1252
         */
1253
        private void definePopUpMenuListener() {                                
1254
                        this.popupMenuListener = new PopupMenuListener() {
1255

    
1256
                        /*
1257
                         *  (non-Javadoc)
1258
                         * @see javax.swing.event.PopupMenuListener#popupMenuCanceled(javax.swing.event.PopupMenuEvent)
1259
                         */
1260
                        public void popupMenuCanceled(PopupMenuEvent e) {
1261
                                logger.debug("MenuCANCELED");
1262
                        }
1263

    
1264
                        /*
1265
                         *  (non-Javadoc)
1266
                         * @see javax.swing.event.PopupMenuListener#popupMenuWillBecomeInvisible(javax.swing.event.PopupMenuEvent)
1267
                         */
1268
                        public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
1269
                                logger.debug("MenuBECOMEINVISIBLE");
1270

    
1271
                                if (!allowInsertString)
1272
                                {
1273
                                        if (!specialSelectionByUserState) {
1274
                                                if ((getSelectedItem() != null) &&(lastSelectedItemPopupUse != null))
1275
                                                {
1276
                                                // If the user has select a different item with the mouse, and this is in the Start View State -> change to the Search View State 
1277
                                                        if (!getSelectedItem().equals(lastSelectedItemPopupUse))
1278
                                                        {
1279
                                                                logger.debug("POPUP: NO SON IGUALES");
1280
                                                                
1281
                                                                // Reports about the written text to the model
1282
                                                                if (model.isDynamicSearch())
1283
                                                                {
1284
                                                                        model.setWrittenText(getSelectedItem().toString());
1285
                                                                        logger.debug("Texto que le envia POPUP al modelo: ->" + getSelectedItem().toString() + "<-");
1286
                                                                }
1287
                                                                        
1288
                                                                if (currentShowState == START_VIEW_STATE)
1289
                                                                {
1290
                                                                        model.setStartStateFlag(false);
1291
                                                                        currentShowState = SEARCH_VIEW_STATE;
1292
                                                                }
1293
                                                                logger.debug("Selected index of item: " + lastSelectedItemPopupUse.toString() + " is " + getSelectedIndex());
1294
                                                        }
1295
                                                        else
1296
                                                                logger.debug("POPUP: SON IGUALES");
1297
                                                }
1298
                                        }
1299
                                }
1300
                        }
1301

    
1302
                        /*
1303
                         *  (non-Javadoc)
1304
                         * @see javax.swing.event.PopupMenuListener#popupMenuWillBecomeVisible(javax.swing.event.PopupMenuEvent)
1305
                         */
1306
                        public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
1307
                                logger.debug("MenuBECOMEVISIBLE");
1308
                                lastSelectedItemPopupUse = getSelectedItem(); // This object is used for know if the user has select a different item with the mouse
1309
                                allowInsertString = false;
1310
                        }                        
1311
                };
1312
        }
1313

    
1314
        /**
1315
         * Configures the component and some of its parts
1316
         */
1317
        private void configure() {
1318
                // Configures the document of the editor of this component
1319
                this.configureDocument();
1320
                
1321
                // Configures the editor (ComboBoxEditor) of this component
1322
                this.configureEditor(this.getEditor());
1323
                
1324
                // Configures the model of this component
1325
                this.configureModel();
1326
                
1327
                // Configures the popup of this component
1328
                this.configurePopUp();
1329
                
1330
                // Configures the text-edition-options popupmenu
1331
                this.configureOptionsEditionByMouse();
1332
        }
1333
        
1334
        /** 
1335
         * Configures the text-edition-options popupmenu
1336
         */
1337
        private void configureOptionsEditionByMouse() {
1338
                this.optionsEditionByMouse.addPropertyChangeListener(editionMenuListener);
1339
        }
1340
        
1341
        /**
1342
         * Configures the popup of this component
1343
         */
1344
        private void configurePopUp() {
1345
                this.addPopupMenuListener(this.popupMenuListener);
1346
        }
1347

    
1348
        /**
1349
         * Configures the model of this component
1350
         */
1351
        private void configureModel() {
1352
                this.model.addListDataListener(this.modelListDataListener);
1353
        }
1354
        
1355
        /**
1356
         * Configures the editor (ComboBoxEditor) of this component
1357
         * 
1358
         * @param newEditor The new editor to configure
1359
         */
1360
        private void configureEditor(ComboBoxEditor newEditor) {
1361
            logger.debug("Configura Editor");
1362
            
1363
        if (newEditor != null) {
1364
                   JTextComponent jTextComponentOfEditor = (JTextComponent) newEditor.getEditorComponent();
1365
                   
1366
                   // Removes some prevous listeners and adds some new others:                
1367
                   
1368
                // Adds the new Key Listener (tries to remove it if it existed before)
1369
                   jTextComponentOfEditor.removeKeyListener(this.editorKeyListener);
1370
                jTextComponentOfEditor.addKeyListener(this.editorKeyListener);
1371

    
1372
            // Disable the focus transversal keys (Example: CTRL+TAB) for enable the TAB key
1373
                jTextComponentOfEditor.setFocusTraversalKeysEnabled(false);
1374
                
1375
            if (this.allowedMouseEditionPopupMenu_Flag)
1376
            {
1377
                        // Adds the new Mouse Listener (tries to remove it if it existed before)
1378
                    jTextComponentOfEditor.removeMouseListener(this.editorMouseListener);
1379
                        jTextComponentOfEditor.addMouseListener(this.editorMouseListener);
1380
            }
1381
             
1382
                // Adds the new Mouse Wheel Listener (tries to remove it if it existed before)
1383
            jTextComponentOfEditor.removeMouseWheelListener(this.editorMouseWheelListener);
1384
                jTextComponentOfEditor.addMouseWheelListener(this.editorMouseWheelListener);
1385
           
1386
                // Adds the new Focus Listener (tries to remove it if it existed before)
1387
                jTextComponentOfEditor.removeFocusListener(this.editorFocusListener);
1388
                jTextComponentOfEditor.addFocusListener(this.editorFocusListener);
1389
 
1390
                   // Adds a caret listener for undo and redo
1391
                jTextComponentOfEditor.addCaretListener(this.caretListener);
1392
                
1393
                // Adds the new document (tries to remove it if it existed before)
1394
                jTextComponentOfEditor.setDocument(this.document);
1395
        }
1396
        }
1397

    
1398
        /**
1399
         * Configures the document of the editor of this component
1400
         */
1401
        private void configureDocument() {
1402
                // Creates the document of the editor of this component
1403
        document = new PlainDocumentTextFormatter();
1404
        document.setJComboBoxItemsSeekerDynamicReference(this);
1405
        
1406
                // Defines and add a Document listener for changes on the document of the editor of this component
1407
                document.addDocumentListener(this.documentListener);
1408
        }
1409
        
1410
        /** 
1411
         * Selects the next item of the popup
1412
         */
1413
        private void selectItemDown() {
1414
                specialSelectionByUserState = true;
1415
                
1416
                if (getItemCount() > 0)
1417
                {
1418
                        if (getSelectedIndex() == (getItemCount()-1))
1419
                                this.setSelectedIndex(0);
1420
                        else
1421
                                this.setSelectedIndex(getSelectedIndex()+1);
1422
                }
1423
        }
1424
        
1425
        /**
1426
         * Selects the previous item of the popup
1427
         */
1428
        private void selectItemUp() {
1429
                specialSelectionByUserState = true;
1430
                
1431
                switch(getSelectedIndex())
1432
                {
1433
                        case -1: case 0:
1434
                                this.setSelectedIndex(getItemCount()-1);
1435
                                break;
1436
                        default:
1437
                                this.setSelectedIndex(getSelectedIndex()-1);
1438
                }
1439
        }
1440
        
1441
        /**
1442
         * This method is invoked when some text has to be removed: With the 'Delete' option of the text-edition-popupmenu or with the 'delete' ('supr'
1443
         *    in spanish keyboard) key
1444
         * 
1445
         * @param editor A reference to the editor component
1446
         */
1447
        private void deleteTextLogic(JTextComponent editor, boolean backSpace_Delete_Mode) {
1448
                // Remove selected text:
1449
                logger.debug("GETMARK: " + editor.getCaret().getMark() + "GETCARETPOSITION" + editor.getCaretPosition());
1450
                int caretPosition = editor.getCaretPosition();
1451
                int markPosition = editor.getCaret().getMark();        
1452
                specialSelectionByUserState = false;
1453
                
1454
                // Get the new text:                
1455
                try {
1456
                        
1457
                        int max_index = Math.max(caretPosition, markPosition);
1458
                        
1459
                        if (caretPosition == markPosition)
1460
                                if (caretPosition == document.getLength()) // If no characters have to be removed
1461
                                        return;
1462
                                else
1463
                                        max_index ++;
1464
                        
1465
                        String newText = document.getText(0, Math.min(caretPosition, markPosition)) + document.getText(max_index, document.getLength() - max_index );
1466
                
1467
                        // Update model and document, and remove character\s
1468
                        switch(currentShowState)
1469
                        {
1470
                                case START_VIEW_STATE :
1471
                                                                        
1472
                                        if (document.getLength() > 0)
1473
                                        {                                                                                
1474
                                                // If dynamic searches:
1475
                                                try {
1476
                                                        // If the search will be dynamic:
1477
                                                        if (isDynamicSearchConfiguration())
1478
                                                        {
1479
                                                                model.setWrittenText(newText);
1480
                                                                logger.debug("Texto que se le env?a delete al modelo desde SUPR: ->" + document.getText(0, document.getLength()) + "<-");                                                
1481
                                                        }
1482
                                                } catch (BadLocationException e) {
1483
                                                        e.printStackTrace();
1484
                                                }        
1485
                                                
1486
                                                model.setStartStateFlag(false);
1487
                                                currentShowState = SEARCH_VIEW_STATE;
1488
                                                
1489
                                                // Remove one or more characters 
1490
                                                characterEliminationLogic(editor, caretPosition, markPosition);                                                
1491
                                        }
1492
                                        break;
1493
                                case SEARCH_VIEW_STATE :
1494
                                        
1495
                                         // If there isn't characters
1496
                                        if (document.getLength() == 0)
1497
                                        {
1498
                                                // This instruction avoids popup could failure when got invisible
1499
                                                hidePopup();
1500
                                                
1501
                                                // If it's a dynamic search
1502
                                                if (isDynamicSearchConfiguration())
1503
                                                {
1504
                                                        model.setWrittenText("");
1505
                                                        logger.debug("Texto que se le env?a delete al modelo desde SUPR: ->\"\"<-");
1506
                                                }
1507
                                                
1508
                                                // Remove one or more characters 
1509
                                                characterEliminationLogic(editor, caretPosition, markPosition);
1510
                                                
1511
                                                // Return to the start view state
1512
                                                model.setStartStateFlag(true);
1513
                                                currentShowState = START_VIEW_STATE;
1514
        
1515
                                                // Select the first Item 
1516
                                                setSelectedIndex(0);
1517
        
1518
                                                if (useHighlight_Flag)
1519
                                                        document.highlightCompletedText(0);
1520
                                        }
1521
                                        else
1522
                                        {                                        
1523
                                                // This instruction avoids popup could failure when got invisible
1524
                                                hidePopup();
1525
                                                
1526
                                                allowInsertString = true;
1527
        
1528
                                        if (lastWasPressedAKeyModifier)
1529
                                        {
1530
                                                logger.debug("PRESSED: " + editor.getText().substring(0));
1531
                                                lastWasPressedAKeyModifier = false;
1532
                                        }
1533
                                                
1534
                                                // If dynamic searches:
1535
                                                try {
1536
                                                        
1537
                                                        // If the search will be dynamic:
1538
                                                        if (isDynamicSearchConfiguration())
1539
                                                        {
1540
                                                                model.setWrittenText(newText);
1541
                                                                logger.debug("Texto que se le env?a delete al modelo desde SUPR: ->" + document.getText(0, document.getLength()) + "<-");                                                
1542
                                                        }
1543
                                                        
1544
                                                        // Remove one or more characters 
1545
                                                        characterEliminationLogic(editor, caretPosition, markPosition);
1546
                                                        
1547
                                                    // Indicate to the model that now is disabled the start view
1548
                                                    if (currentShowState == START_VIEW_STATE)
1549
                                                    {
1550
                                                            model.setStartStateFlag(false);
1551
                                                            currentShowState = SEARCH_VIEW_STATE;
1552
                                                    }
1553
                                                } catch (BadLocationException e) {
1554
                                                        // TODO Auto-generated catch block
1555
                                                        e.printStackTrace();
1556
                                                }
1557
                                        }                                                                        
1558
                                        break;                                                                        
1559
                        }
1560
                
1561
                        updatePopUpView();
1562
                        
1563
                } catch (BadLocationException e1) {
1564
                        // TODO Auto-generated catch block
1565
                        e1.printStackTrace();
1566
                }
1567
        }
1568
        
1569
        /**
1570
         * This method has the logic for remove one or more characters 
1571
         * 
1572
         * @param editor A reference to the editor
1573
         * @param caretPosition Position of the caret in the text
1574
         */
1575
        private void characterEliminationLogic(JTextComponent editor, int caretPosition, int markPosition) {
1576
                // First: Remove character\s (only if hasn't been done a 'cut' mouse operation)
1577
                if (cutOperationDone) {
1578
                        cutOperationDone = false;
1579
                }
1580
                else {
1581
                        try {                        
1582
                                // If no characters are selected
1583
                                if (markPosition == caretPosition) {
1584
                                        // Remove the character which is on the right of the caret position
1585
                                        if (caretPosition < document.getLength())                                                                        
1586
                                                document.remove(caretPosition, 1);                                                                                
1587
                                }
1588
                                else // If there are characters selected
1589
                                {
1590
                                        // Remove the characters which are selected
1591
                                        int length = Math.abs(markPosition - caretPosition);
1592
                                        
1593
                                        // Remove the characters which are selected
1594
                                        document.remove(Math.min(markPosition, caretPosition), length);
1595
                                }
1596
                        } catch (BadLocationException e) {
1597
                                e.printStackTrace();
1598
                        }
1599
                }        
1600
        }
1601

    
1602
        /**
1603
         * Returns true if the model has a dynamic search configuration
1604
         * 
1605
         * @return 'true' if the model has a dynamic searchh configuration, else returns 'false'.
1606
         */
1607
        private boolean isDynamicSearchConfiguration() {
1608
                switch(model.getSearchBehavior())
1609
                {
1610
                        case AbstractDefaultComboBoxItemsSeekerConfigurableModel.MAINTAIN_ORIGINAL_POSITION_DYNAMIC_SEARCH :
1611
                        case AbstractDefaultComboBoxItemsSeekerConfigurableModel.ORDERED_DYNAMIC_SEARCH :
1612
                        case AbstractDefaultComboBoxItemsSeekerConfigurableModel.DISORDERED_DYNAMIC_SEARCH :
1613
                                return true;
1614
                }
1615
                
1616
                return false;
1617
        }
1618
        
1619
        /**
1620
         * Selects the first item added to the model
1621
         */
1622
        public void selectFirstItemAddedToModel() {
1623
                // Select the first Item added
1624
                Object item = model.getFirstItemAdded();
1625
                if (item != null)
1626
                        setSelectedItem(item);
1627
        }
1628

    
1629
    
1630
        /**
1631
     * Updates the popup view, this solves the problem of updating items that are showed, but has the problem that could produce winking
1632
     */
1633
        private void updatePopUpView() {
1634
            // HidePopUp + ShowPopUp to force update the popup list of items
1635
                hidePopup();
1636
                showPopup();
1637
                this.setVisible(true);
1638
        
1639
    }
1640
        
1641
        /**
1642
         * This method has the logic for a "undo" operation
1643
         */
1644
        private void undoOperationLogic() {
1645
                logger.debug("UNDO PRESSED");
1646
                try {
1647
            if (undoManager.canUndo()) {
1648
                    undoManager.undo();
1649
                    
1650
                    String newPattern = document.getText(0, document.getLength());
1651
                            
1652
                                model.setWrittenText(newPattern);
1653
                                
1654
                                document.formatText(document.lookupItem(), 0);
1655
                                
1656
                                if (isPopupVisible())
1657
                                        updatePopUpView();
1658
                    
1659
                    logger.debug("Undo por teclado realizado");
1660
            }
1661
                } catch (BadLocationException e) {
1662
                        e.printStackTrace();
1663
                } catch (CannotUndoException e) {
1664
                e.printStackTrace();
1665
        }
1666
        }
1667
        
1668
        /**
1669
         * This method has the logic for a "redo" operation
1670
         */
1671
        private void redoOperationLogic() {
1672
                logger.debug("REDO PRESSED");
1673
        try {
1674
            if (undoManager.canRedo()) {
1675
                            undoManager.redo();
1676
                            
1677
                     String newPattern = document.getText(0, document.getLength());
1678
                           
1679
                               model.setWrittenText(newPattern);
1680
                               
1681
                               document.formatText(document.lookupItem(), 0);
1682
                               
1683
                               if (isPopupVisible())
1684
                                        updatePopUpView();
1685
                            
1686
                    logger.debug("Redo por teclado realizado");
1687
            }
1688
            } catch (CannotRedoException e) {
1689
                    e.printStackTrace();
1690
            } catch (BadLocationException e) {
1691
                    e.printStackTrace();
1692
            }
1693
        }    
1694
    
1695
    ////// REDEFINITION OF SOME METHODS OF JCOMBOBOX //////
1696

    
1697
        /*
1698
         *  (non-Javadoc)
1699
         * @see javax.swing.JComboBox#actionPerformed(java.awt.event.ActionEvent)
1700
         */
1701
        public void actionPerformed(ActionEvent e)
1702
        {
1703
                super.actionPerformed(e);
1704

    
1705
                // This flag indicates to the 'insertString' method of the PlainDocumentSeeker that the text of the item selected or written by the user
1706
                //  hasn't been written on the TextEditor of ths component
1707
                selecting = false;
1708
        }
1709

    
1710
        /*
1711
     * (non-Javadoc)
1712
     * @see javax.swing.JComboBox#addItem(java.lang.Object)
1713
     */
1714
        public void addItem(Object anObject) {
1715
                // Adds the item to this component                
1716
                model.addElement(anObject);
1717
                
1718
                // Set the last selected item -> by default select the first item:
1719
                // This is used to show the first item that model returns when we add a new item. This also
1720
                //  corrects the 'mistake' produced by 'ComboBoxModel' when is added a new item and there wasn't
1721
                //  any selected -> that the 'ComboBoxModel' selects by default the first added (that in our case 
1722
                //  might not be the same as the first item seen in the popup list)
1723
                if (this.getSelectedIndex() != 0)
1724
                {
1725
                        this.setSelectedIndex(0);
1726
//                        this.selectedItem = this.getSelectedItem();
1727
                }
1728
        }
1729
    
1730
        /*
1731
     * (non-Javadoc)
1732
     * @see javax.swing.JComboBox#removeAllItems()
1733
     */
1734
        public void removeAllItems() {
1735
            // Removes all items from the model
1736
            model.removeAllElements();
1737
            
1738
            currentShowState = BEGINNING_VIEW_STATE;
1739
    }
1740
    
1741
        /*
1742
     * (non-Javadoc)
1743
     * @see javax.swing.JComboBox#removeItem(java.lang.Object)
1744
     */
1745
        public void removeItem(Object anObject) {
1746
            // Removes an object from the model
1747
            model.removeElement(anObject);
1748
            
1749
            if (model.getSize() == 0)
1750
                    currentShowState = BEGINNING_VIEW_STATE;
1751
    }
1752

    
1753
        /*
1754
     * (non-Javadoc)
1755
     * @see javax.swing.JComboBox#removeItemAt(int)
1756
     */
1757
        public void removeItemAt(int anIndex) {
1758
               // Removes an object, which is in a determinated position (index), from the model
1759
            model.removeElementAt(anIndex);
1760
            
1761
            if (model.getSize() == 0)
1762
                    currentShowState = BEGINNING_VIEW_STATE;
1763
    }
1764
    
1765
        /*
1766
     * (non-Javadoc)
1767
     * @see javax.swing.JComboBox#getItemCount()
1768
     */
1769
        public int getItemCount() {
1770
            return model.getSize();
1771
    }
1772
    
1773
        /*
1774
     * (non-Javadoc)
1775
     * @see javax.swing.JComboBox#getItemAt(int)
1776
     */
1777
        public Object getItemAt(int index) {
1778
            return model.getElementAt(index);
1779
    }
1780
    
1781
        /*
1782
     * (non-Javadoc)
1783
     * @see javax.swing.JComboBox#setModel(javax.swing.ComboBoxModel)
1784
     */
1785
        public void setModel(ComboBoxModel aModel) {            
1786
            // Depending on the type of class of the current object, this object will execute different code
1787
            if ( (aModel instanceof ComboBoxSingularItemsSeekerConfigurableModel) || (aModel instanceof ComboBoxItemsSeekerConfigurableModel) )
1788
            {
1789
                    super.setModel(aModel);
1790
                    
1791
                    if (aModel instanceof ComboBoxSingularItemsSeekerConfigurableModel)
1792
                            model = (ComboBoxSingularItemsSeekerConfigurableModel)super.getModel();
1793
                    else
1794
                            model = (ComboBoxItemsSeekerConfigurableModel)super.getModel();
1795
                    
1796
                    // If we insert a model with items -> select by default the first
1797
                    if (aModel.getSize() > 0)
1798
                            this.setSelectedIndex(0);
1799
                    else
1800
                    {
1801
                            // Else -> set the default index (-1) and current showed string ("")
1802
                            this.setSelectedIndex(-1);
1803
                    }
1804
                    
1805
                    this.configureModel();
1806
            }
1807
            else
1808
            {
1809
                    // If it's an instance of DefaultComboBoxModel:
1810
                    super.setModel(aModel);                    
1811
            }                    
1812
     }
1813
    
1814
        /*
1815
     * (non-Javadoc)
1816
     * @see javax.swing.JComboBox#setSelectedIndex(int)
1817
     */
1818
        public void setSelectedIndex(int anIndex) {
1819
            super.setSelectedIndex(anIndex);
1820
    }
1821
    
1822
        /*
1823
     * (non-Javadoc)
1824
     * @see javax.swing.JComboBox#getSelectedIndex()
1825
     */
1826
        public int getSelectedIndex() {
1827
            Object item = this.getSelectedItem();
1828
            
1829
            if (item == null)
1830
                    return -1;
1831
            else
1832
                    return model.getIndexOf(item);
1833
    }
1834
    
1835
        /*
1836
     *  (non-Javadoc)
1837
     * @see javax.swing.JComboBox#setSelectedItem(java.lang.Object)
1838
     */
1839
        public void setSelectedItem(Object anObject) {
1840
            super.setSelectedItem(anObject);
1841
    }
1842
    
1843
    ////// END REDEFINITION OF SOME METHODS OF JCOMBOBOX //////
1844
   
1845
        
1846

    
1847
        ////// METHODS FOR THE BEHAVIOR FLAGS  //////
1848

    
1849
        /**
1850
         * This method tests the configuration of the flags and returns true or false if its ok or not with the
1851
         *   logical behavior of this component
1852
         * 
1853
         * @return boolean True if the configuration of the flags is oks, false if not
1854
         */
1855
        public boolean testFlagsConfigurationOK() {
1856
                return this.model.testFlagsConfigurationOK();
1857
        }
1858
        
1859
        /**
1860
         * @see AbstractDefaultComboBoxItemsSeekerConfigurableModel#getStartBehavior()
1861
         */
1862
        public int getStartBehavior() {
1863
                return this.model.getStartBehavior();
1864
        }
1865
        
1866
        /**
1867
         * @see AbstractDefaultComboBoxItemsSeekerConfigurableModel#setStartBehavior(int)
1868
         */
1869
        public void setStartBehavior(int start_Behavior) {
1870
                this.model.setStartBehavior(start_Behavior);
1871
                
1872
                if (!this.model.testFlagsConfigurationOK())
1873
                        JOptionPane.showMessageDialog(this, Messages.getText("errorMessageJComboBoxItemsSeekerConfigurable"), Messages.getText("exportJOP2Title"), JOptionPane.ERROR_MESSAGE);
1874
        }
1875

    
1876
        /**
1877
         * @see AbstractDefaultComboBoxItemsSeekerConfigurableModel#getSearchBehavior()
1878
         */
1879
        public int getSearchBehavior() {
1880
                return this.model.getSearchBehavior();
1881
        }
1882

    
1883
        /**
1884
         * @see AbstractDefaultComboBoxItemsSeekerConfigurableModel#setSearchBehavior(int)
1885
         */
1886
        public void setSearchBehavior(int search_Behavior) {
1887
                this.model.setSearchBehavior(search_Behavior);
1888
                
1889
                if (!this.model.testFlagsConfigurationOK())
1890
                        JOptionPane.showMessageDialog(this, Messages.getText("errorMessageJComboBoxItemsSeekerConfigurable"), Messages.getText("exportJOP2Title"), JOptionPane.ERROR_MESSAGE);
1891
        }
1892
        
1893
        /**
1894
         * @see AbstractDefaultComboBoxItemsSeekerConfigurableModel#isCaseSensitive_Flag()
1895
         */
1896
        public boolean isCaseSensitive_Flag() {
1897
                return this.model.isCaseSensitive_Flag();
1898
        }
1899
        
1900
        /**
1901
         * @see AbstractDefaultComboBoxItemsSeekerConfigurableModel#setCaseSensitive_Flag(boolean)
1902
         */
1903
        public void setCaseSensitive_Flag(boolean case_Sensitive) {
1904
                this.model.setCaseSensitive_Flag(case_Sensitive);
1905
                
1906
                if (!this.model.testFlagsConfigurationOK())
1907
                        JOptionPane.showMessageDialog(this, Messages.getText("errorMessageJComboBoxItemsSeekerConfigurable"), Messages.getText("exportJOP2Title"), JOptionPane.ERROR_MESSAGE);
1908
        }
1909

    
1910
        /**
1911
         * Returns the 'only_One_Color_On_Text' configuration value of this component. Configuration values are: 
1912
         *   + true -> always uses black color on text
1913
         *   + false -> by default uses black color on text, but if text written by user doesn't match with any item, text will be on red color
1914
         * 
1915
         * @return 'only_One_Color_On_Text' configuration
1916
         */
1917
        public boolean isOnlyOneColorOnText_Flag() {
1918
                return onlyOneColorOnText_Flag;
1919
        }
1920
        
1921
        /**
1922
         * Sets the 'only_One_Color_On_Text' configuration value for this component. Configuration values are: 
1923
         *   + true -> always uses black color on text
1924
         *   + false -> by default uses black color on text, but if text written by user doesn't match with any item, text will be on red color
1925
         * 
1926
         * @oaram A boolean value for 'only_One_Color_On_Text' configuration flag
1927
         */
1928
        public void setOnlyOneColorOnText_Flag(boolean only_One_Color) {
1929
                this.onlyOneColorOnText_Flag = only_One_Color;
1930
                
1931
                if (!this.model.testFlagsConfigurationOK())
1932
                        JOptionPane.showMessageDialog(this, Messages.getText("errorMessageJComboBoxItemsSeekerConfigurable"), Messages.getText("exportJOP2Title"), JOptionPane.ERROR_MESSAGE);
1933
        }
1934

    
1935
        /**
1936
         * Returns the 'beep_Enabled' configuration value of this component. Configuration values are: 
1937
         *   + true -> a beep-sound is listened when no item matches with the text written.
1938
         *   + false -> no sound is listened.
1939
         * 
1940
         * @return 'beep_Enabled' configuration
1941
         */
1942
        public boolean isBeepEnabled_Flag() {
1943
                return this.beepEnabled_Flag;
1944
        }
1945
        
1946
        /**
1947
         * Sets the 'beep_Enabled' configuration value for this component. Configuration values are: 
1948
         *   + true -> a beep-sound is listened when no item matches with the text written.
1949
         *   + false -> no sound is listened.
1950
         * 
1951
         * @oaram A boolean value for 'beep_Enabled' configuration flag
1952
         */
1953
        public void setBeepEnabled_Flag(boolean beep_Enabled) {
1954
                this.beepEnabled_Flag = beep_Enabled;
1955
        }        
1956
        
1957
        /**
1958
         * Returns the 'complete_Matched_Item' configuration value of this component. Configuration values are: 
1959
         *   + true -> When user writes, shows also the rest of the current matched item that user hasn't written.
1960
         *   + false -> Only shows the text written by the user when user is writting.
1961
         * 
1962
         * @return 'complete_Matched_Item' configuration
1963
         */
1964
        public boolean isCompleteMatchedItem_Flag() {
1965
                return this.completeMatchedItem_Flag;
1966
        }
1967
        
1968
        /**
1969
         * Sets the 'complete_Matched_Item' configuration value for this component. Configuration values are: 
1970
         *   + true -> a beep-sound is listened when no item matches with the text written.
1971
         *   + false -> no sound is listened.
1972
         * 
1973
         * @oaram A boolean value for 'complete_Matched_Item' configuration flag
1974
         */
1975
        public void setCompleteMatchedItem_Flag(boolean Complete_Matched_Item) {
1976
                this.completeMatchedItem_Flag = Complete_Matched_Item;
1977
        }
1978
        
1979
        /**
1980
         * Returns the 'allowed_Repeated_Items' configuration value of this component. Configuration values are: 
1981
         * Uses one of the two models according the value of this flag:
1982
     *    + true -> Uses 'ComboBoxItemsSeekerConfigurableModel' as model (this could work slowly).
1983
     *    + false -> Uses 'ComboBoxSingularItemsSeekerConfigurableModel' as model.
1984
     *    
1985
         * @return 'allowed_Repeated_Items' configuration
1986
         */
1987
        public boolean isAllowedRepeatedItems_Flag() {
1988
                return this.allowedRepeatedItems_Flag;
1989
        }
1990
        
1991
        /**
1992
         * Sets the 'allowed_Repeated_Items' configuration value for this component. Configuration values are: 
1993
         * Uses one of the two models according the value of this flag:
1994
     *    + true -> Uses 'ComboBoxItemsSeekerConfigurableModel' as model (this could work slowly).
1995
     *    + false -> Uses 'ComboBoxSingularItemsSeekerConfigurableModel' as model.
1996
         * 
1997
         * @oaram A boolean value for 'allowed_Repeated_Items' configuration flag
1998
         */
1999
        public void setAllowedRepeatedItems_Flag(boolean allowed_Repeated_Items) {
2000
                this.allowedRepeatedItems_Flag = allowed_Repeated_Items;
2001
                
2002
                try {
2003
                        AbstractDefaultComboBoxItemsSeekerConfigurableModel model_temp;
2004
                        
2005
                        // Add the items to the new model
2006
                        if (allowed_Repeated_Items)
2007
                                model_temp = new ComboBoxItemsSeekerConfigurableModel(model.getParentAllData());
2008
                        else
2009
                                model_temp = new ComboBoxSingularItemsSeekerConfigurableModel(model.getParentAllData());
2010
                                                        
2011
                        // Copy the behavior of the model
2012
                        model_temp.setStartBehavior(this.getStartBehavior());
2013
                        model_temp.setSearchBehavior(this.getSearchBehavior());
2014
                        model_temp.setCaseSensitive_Flag(this.isCaseSensitive_Flag());
2015
                        
2016
                        // Set the new model
2017
                        this.setModel(model_temp);
2018
                }
2019
                catch(Exception e)
2020
                {
2021
                        e.printStackTrace();
2022
                }
2023
        }
2024
        
2025
        /**
2026
         * Returns the 'allowed_Mouse_Edition_Popup_Menu' configuration value of this component. Configuration values are: 
2027
         *   + true -> a 'PopupMenu' for text edition that appears when the user clicks on the text-edition-field with the right
2028
         *                button of the mouse.
2029
         *   + false -> that 'PopupMenu' won't appear. 
2030
         * 
2031
         * @return 'allowed_Mouse_Edition_Popup_Menu' configuration
2032
         */
2033
        public boolean isAllowedMouseEditionPopupMenu_Flag() {
2034
                return this.allowedMouseEditionPopupMenu_Flag;
2035
        }
2036

    
2037
        /**
2038
         * Sets the 'allowed_Mouse_Edition_Popup_Menu' configuration value for this component. Configuration values are: 
2039
         *   + true -> a 'PopupMenu' for text edition that appears when the user clicks on the text-edition-field with the right
2040
         *                button of the mouse.
2041
         *   + false -> that 'PopupMenu' won't appear. 
2042
         * 
2043
         * @oaram A boolean value for 'allowed_Mouse_Edition_Popup_Menu' configuration flag
2044
         */
2045
        public void setAllowedMouseEditionPopupMenu_Flag(boolean allowed_Mouse_Edition_Popup_Menu) {
2046
                JTextComponent editor = (JTextComponent) this.getEditor().getEditorComponent();
2047
                
2048
                if (this.allowedMouseEditionPopupMenu_Flag != allowed_Mouse_Edition_Popup_Menu)
2049
                {
2050
                        // If now is allowed -> adds the mouse listener
2051
                        if (allowed_Mouse_Edition_Popup_Menu)
2052
                    editor.addMouseListener(this.editorMouseListener);
2053
                        else // If now isn't allowed
2054
                                editor.removeMouseListener(this.editorMouseListener);
2055
                }
2056

    
2057
                this.allowedMouseEditionPopupMenu_Flag = allowed_Mouse_Edition_Popup_Menu;
2058
        }
2059

    
2060
        /**
2061
         * Returns the 'to_Force_To_Only_Coincidences_In_The_Search' configuration value of this component. Configuration values are: 
2062
         *   + true -> If the user has written some text that doesn't mach with any item, and press the 'Enter' key for close the popup the user will
2063
         *                see written in the text-edition-field the last item which matched with the text written, or the first item of the model if
2064
         *                there wasn't.
2065
         *   + false -> If no item matches with the text written and the user presses the 'Enter' key, no item will be selected.
2066
         * 
2067
         * @return 'to_Force_To_Only_Coincidences_In_The_Search' configuration
2068
         */
2069
        public boolean isToForceToOnlyCoincidencesInTheSearch_Flag() {
2070
                return this.toForceToOnlyCoincidencesInTheSearch_Flag;
2071
        }
2072
        
2073
        /**
2074
         * Sets the 'to_Force_To_Only_Coincidences_In_The_Search' configuration value for this component. Configuration values are: 
2075
         *   + true -> If the user has written some text that doesn't mach with any item, and press the 'Enter' key for close the popup the user will
2076
         *                see written in the text-edition-field the last item which matched with the text written, or the first item of the model if
2077
         *                there wasn't.
2078
         *   + false -> If no item matches with the text written and the user presses the 'Enter' key, no item will be selected.
2079
         * 
2080
         * @oaram A boolean value for 'to_Force_To_Only_Coincidences_In_The_Search' configuration flag
2081
         */
2082
        public void setToForceToOnlyCoincidencesInTheSearch_Flag(boolean to_Force_To_Only_Coincidences_In_The_Search) {
2083
                this.toForceToOnlyCoincidencesInTheSearch_Flag = to_Force_To_Only_Coincidences_In_The_Search;
2084
        }
2085

    
2086
        /**
2087
         * Returns the 'use_highlight' configuration value of this component. Configuration values are: 
2088
         *   + true -> marks characters of the text in the text-edition-field with a highlight.
2089
         *   + false -> doesn't do that.
2090
         * 
2091
         * @return 'use_Highlight' configuration
2092
         */
2093
        public boolean isUseHighLight_Flag() {
2094
                return this.useHighlight_Flag;
2095
        }
2096
        
2097
        /**
2098
         * Sets the 'use_highlight' configuration value for this component. Configuration values are: 
2099
         *   + true -> marks characters of the text in the text-edition-field with a highlight.
2100
         *   + false -> doesn't do that.
2101
         * 
2102
         * @oaram A boolean value for 'use_Highlight' configuration flag 
2103
         */
2104
        public void setUseHighLight_Flag(boolean use_Highlight) {
2105
                this.useHighlight_Flag = use_Highlight;
2106
        }
2107

    
2108
        /**
2109
         * Returns the 'select_An_Item_When_Loses_Focus' configuration value of this component. Configuration values are:
2110
     *   + true -> If user or an application makes component lose its focus, an item will be selected.
2111
     *   + false -> If user or an application makes component lose its focus, the component will stay as it was.
2112
     *   
2113
     * @return 'select_An_Item_When_Loses_Focus' configuration  
2114
         */
2115
        public boolean isSelectAnItemWhenLosesFocus_Flag() {
2116
                return this.selectAnItemWhenLosesFocus_Flag;
2117
        }
2118
        
2119
        /**
2120
         *  Sets the 'select_An_Item_When_Loses_Focus' configuration value for this component. Configuration values are: 
2121
     *   + true -> If user or an application makes component lose its focus, an item will be selected.
2122
     *   + false -> If user or an application makes component lose its focus, the component will stay as it was.
2123
         * 
2124
         * @oaram A boolean value for 'select_An_Item_When_Loses_Focus' configuration flag
2125
         */
2126
        public void setSelectAnItemWhenLosesFocus_Flag(boolean select_An_Item_When_Loses_Focus) {
2127
                this.selectAnItemWhenLosesFocus_Flag = select_An_Item_When_Loses_Focus;
2128
        }
2129
        
2130
        ////// END METHODS FOR THE BEHAVIOR FLAGS  //////
2131
        
2132
        
2133
    
2134
    ////// OTHER METHODS //////
2135
        
2136
        /**
2137
     * Sets the limit of actions that can hold the UndoManager of this component
2138
     * 
2139
     * @param limit
2140
     */
2141
        public void setUndoRedoLimitActions(int limit) {
2142
            this.undoRedoLimitActions = limit;
2143
            undoManager.setLimit(undoRedoLimitActions);
2144
    }
2145
    
2146
        /**
2147
     * Gets the limit of actions that can hold the UndoManager:
2148
     * 
2149
     * @return int 
2150
     */
2151
        public int getUndoRedoLimitActions() {
2152
            return this.undoRedoLimitActions;
2153
    }
2154
     
2155
    ////// END OTHER METHODS //////        
2156
        
2157
        
2158
        /**
2159
         * Inner class that inherits of the class PlainDocument, and is used for manipulate the text that has the document of the editor of this component
2160
         * This class is also optimized for items seek, changes the color of the text or sets highlight if it's needed.
2161
         * 
2162
         * @author Pablo Piqueras Bartolom? (p_queras@hotmail.com)
2163
         */
2164
        private class PlainDocumentTextFormatter extends PlainDocument {
2165
                private static final long serialVersionUID = 4158213349939840209L;
2166
                private JComboBoxItemsSeekerConfigurable comboBoxReference;                
2167

    
2168
                /**
2169
                 * Default Constructor
2170
                 */
2171
                public PlainDocumentTextFormatter() {
2172
                        super();
2173
                        this.initialize();
2174
                }
2175
                
2176
                /**
2177
                 * This method makes some initialize operations 
2178
                 */
2179
                private void initialize() {
2180
                        this.configureUndoManager();
2181
                }
2182
                
2183
                /**
2184
                 * Configures the UndoManager for Undo-Redo operations
2185
                 */
2186
                private void configureUndoManager() {
2187
                // Listen for undo and redo events
2188
                this.addUndoableEditListener(new UndoableEditListener() {
2189
                        /*
2190
                         * (non-Javadoc)
2191
                         * @see javax.swing.event.UndoableEditListener#undoableEditHappened(javax.swing.event.UndoableEditEvent)
2192
                         */
2193
                    public void undoableEditHappened(UndoableEditEvent evt) {
2194
                            logger.debug("UNDOABLE EVENT");
2195
                                        undoManager.addEdit(evt.getEdit());
2196
                    }
2197
                });
2198
                }
2199

    
2200
                /**
2201
                 * Sets a reference of the combo_Box
2202
                 * 
2203
                 * @param combo_Box A reference to the class that contains this.
2204
                 */
2205
                public void setJComboBoxItemsSeekerDynamicReference(JComboBoxItemsSeekerConfigurable combo_Box) {
2206
                        comboBoxReference = combo_Box;
2207
                }
2208
                
2209
                /*
2210
                 *  (non-Javadoc)
2211
                 * @see javax.swing.text.Document#remove(int, int)
2212
                 */
2213
                public void remove(int offs, int len) throws BadLocationException {
2214
                // return immediately when selecting an item
2215
                if (selecting) return;
2216

    
2217
                if (hitBackspace)
2218
                {
2219
                    // user hit backspace => move the selection backwards
2220
                    // old item keeps being selected
2221
                    if (offs>0)
2222
                    {
2223
                        if (hitBackspaceOnSelection)
2224
                                offs--;
2225
                    }
2226
                    else
2227
                    {
2228
                        // User hit backspace with the cursor positioned on the start => beep
2229
                            if (beepEnabled_Flag)
2230
                                    comboBoxReference.getToolkit().beep(); // when available use: UIManager.getLookAndFeel().provideErrorFeedback(comboBox);
2231
                    }
2232
                    
2233
                    if (useHighlight_Flag)
2234
                                        highlightCompletedText(offs);
2235
                            
2236
                    hitBackspace=false;
2237
                }
2238
                else
2239
                {
2240
                        logger.debug("REMOVES OFFS: " + offs + ", LEN: " + len);
2241
                        super.remove(offs, len);
2242
                }  
2243

    
2244
                formatText(lookupItem(), offs);
2245
            }
2246

    
2247
                /* NUEVA VERSI?N
2248
                 *  (non-Javadoc)
2249
                 * @see javax.swing.text.Document#insertString(int, java.lang.String, javax.swing.text.AttributeSet)
2250
                 */
2251
            public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
2252
                    Object item = lookupItem();
2253
                          
2254
                    // If we have to complete the text: only write the part of the item not written
2255
                        if ((completeMatchedItem_Flag) && (item != null) && (!itemSelectedByMouse)) {                                                    
2256
                                editor.getEditorComponent().setForeground(Color.BLACK);
2257
                                super.insertString(super.getLength(), item.toString().substring(super.getLength(), item.toString().length()), a);
2258
                                
2259
                                if (!specialSelectionByUserState)
2260
                                        offs += Math.min(str.length(), document.getLength());
2261
                        }
2262
                        else {
2263
                                super.insertString(offs, str, a);
2264
                                itemSelectedByMouse = false;
2265
                                offs += str.length();
2266
                        }
2267
//                        offs += Math.min(str.length(), document.getLength());
2268
                        formatText(item, offs);
2269
            }
2270
                
2271
                /**
2272
                 * Marks text since 'start' position to its end on a grey color
2273
                 *  
2274
                 * @param start Start position for mark the text
2275
                 */
2276
                public void highlightCompletedText(int start) {
2277
                    JTextComponent editor = (JTextComponent) getEditor().getEditorComponent();
2278
                    
2279
                editor.setCaretPosition(document.getLength());
2280
                editor.moveCaretPosition(start);
2281
            }
2282
                
2283
                /**
2284
                 * If the pattern doesn't match with the selected/current item changes the color of the text to red if isOnlyOneColorOnText_Flag=true, else 
2285
             *    sets the color of the text black.
2286
                 * 
2287
                 * @param pattern
2288
                 */
2289
                private void formatText(Object item, int offs) {                    
2290
                    if (!comboBoxReference.isOnlyOneColorOnText_Flag()) {
2291
                            if ((item == null) && (currentShowState != START_VIEW_STATE)) {
2292
                                    editor.getEditorComponent().setForeground(Color.RED);
2293
                                    logger.debug("Pone a Rojo Lookup");
2294
                            }
2295
                            else {
2296
                                    editor.getEditorComponent().setForeground(Color.BLACK);
2297
                                    logger.debug("Pone a Negro Lookup");
2298
                            }
2299
                            
2300
                                // If it's necessary, produces a "beep" sound
2301
                                if ((beepEnabled_Flag) && (item == null) && (!lastWasTheBeginningState)) {
2302
                                        comboBoxReference.getToolkit().beep(); // when available use: UIManager.getLookAndFeel().provideErrorFeedback(comboBox);
2303
                                }
2304
                    }
2305
                    
2306
                    if (useHighlight_Flag) {
2307
                                  
2308
                            // Select
2309
                            highlightCompletedText(offs);
2310
                          }
2311
                }
2312
                
2313
                /**
2314
                 * Returns the current item in the popup of JComboBox or the selected item. If there is no item, returns null
2315
                 * 
2316
                 * @return An object
2317
                 */
2318
                private Object lookupItem() {
2319
                Object item = null;
2320
                    if (model.getSize() > 0) {
2321
                            if (specialSelectionByUserState) {
2322
                                    item = model.getSelectedItem();
2323
                            }
2324
                            else
2325
                                    item = model.getElementAt(0);
2326
                    }
2327
                    
2328
                    return item;
2329
                }
2330
        }
2331
}