OpenConcerto

Dépôt officiel du code source de l'ERP OpenConcerto
sonarqube

svn://code.openconcerto.org/openconcerto

Rev

Rev 83 | Rev 132 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
83 ilm 1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
5
 *
6
 * The contents of this file are subject to the terms of the GNU General Public License Version 3
7
 * only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
8
 * copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
9
 * language governing permissions and limitations under the License.
10
 *
11
 * When distributing the software, include this License Header Notice in each file.
12
 */
13
 
14
 package org.openconcerto.sql.sqlobject;
15
 
16
import org.openconcerto.sql.model.SQLField;
17
import org.openconcerto.sql.model.SQLRow;
18
import org.openconcerto.sql.model.SQLRowAccessor;
19
import org.openconcerto.sql.model.SQLSelect;
20
import org.openconcerto.sql.model.SQLTable;
21
import org.openconcerto.sql.model.Where;
22
import org.openconcerto.sql.request.MultipleSQLSelectExecutor;
23
import org.openconcerto.ui.component.text.TextComponent;
24
import org.openconcerto.utils.CompareUtils;
25
import org.openconcerto.utils.OrderedSet;
26
import org.openconcerto.utils.SwingWorker2;
27
import org.openconcerto.utils.checks.MutableValueObject;
28
import org.openconcerto.utils.model.DefaultIMutableListModel;
29
import org.openconcerto.utils.text.DocumentFilterList;
30
import org.openconcerto.utils.text.DocumentFilterList.FilterType;
31
import org.openconcerto.utils.text.LimitedSizeDocumentFilter;
32
 
33
import java.awt.Component;
34
import java.awt.GridLayout;
35
import java.awt.event.ComponentEvent;
36
import java.awt.event.ComponentListener;
37
import java.awt.event.FocusEvent;
38
import java.awt.event.FocusListener;
39
import java.awt.event.KeyEvent;
40
import java.awt.event.KeyListener;
41
import java.beans.PropertyChangeListener;
42
import java.beans.PropertyChangeSupport;
43
import java.sql.SQLException;
44
import java.util.ArrayList;
45
import java.util.Iterator;
46
import java.util.List;
47
import java.util.Stack;
48
import java.util.Vector;
49
 
50
import javax.swing.JComponent;
51
import javax.swing.JPanel;
52
import javax.swing.JTextField;
53
import javax.swing.SwingUtilities;
54
import javax.swing.event.DocumentEvent;
55
import javax.swing.event.DocumentListener;
56
import javax.swing.text.AbstractDocument;
57
import javax.swing.text.DocumentFilter;
58
import javax.swing.text.JTextComponent;
59
 
60
public class ITextArticleWithCompletion extends JPanel implements DocumentListener, TextComponent, MutableValueObject<String>, IComboSelectionItemListener {
61
 
62
    public static int SQL_RESULT_LIMIT = 50;
63
 
64
    public static final int MODE_STARTWITH = 1;
65
    public static final int MODE_CONTAINS = 2;
66
 
67
    private JTextComponent text;
68
 
69
    private DefaultIMutableListModel<IComboSelectionItem> model = new DefaultIMutableListModel<IComboSelectionItem>();
70
 
71
    private boolean completionEnabled = true;
72
 
73
    private SQLRowAccessor selectedRow = null;
74
 
75
    private boolean selectAuto = true;
76
 
77
    protected ITextWithCompletionPopUp popup;
78
 
79
    OrderedSet<SelectionRowListener> listeners = new OrderedSet<SelectionRowListener>();
80
    Component popupInvoker;
81
 
82
    private boolean isLoading = false;
83
    private SQLRowAccessor rowToSelect = null;
84
 
85
    private String fillWith = "CODE";
86
    private final PropertyChangeSupport supp;
87
 
88
    private final SQLTable tableArticle, tableArticleFournisseur;
89
 
90
    // Asynchronous filling
91
    private Thread searchThread;
92
    private int autoCheckDelay = 1000;
93
    private boolean disposed = false;
94
    private Stack<String> searchStack = new Stack<String>();
95
    private boolean autoselectIfMatch;
96
    private static final int PAUSE_MS = 150;
97
 
98
    public ITextArticleWithCompletion(SQLTable tableArticle, SQLTable tableARticleFournisseur) {
99
        this.tableArticle = tableArticle;
100
        this.tableArticleFournisseur = tableARticleFournisseur;
101
        this.supp = new PropertyChangeSupport(this);
102
        this.popup = new ITextWithCompletionPopUp(this.model, this);
103
        this.text = new JTextField();
104
        this.setLayout(new GridLayout(1, 1));
105
        this.add(this.text);
106
        setTextEditor(this.text);
107
        setPopupInvoker(this);
108
 
109
        //
110
        disposed = false;
111
        searchThread = new Thread() {
112
            public void run() {
113
                while (!disposed) {
114
                    if (autoCheckDelay == 0) {
115
                        autoCheckDelay = -1;
116
                        SwingUtilities.invokeLater(new Runnable() {
117
                            @Override
118
                            public void run() {
119
                                loadAutoCompletion();
120
                            }
121
                        });
122
 
123
                    } else if (autoCheckDelay > 0) {
124
                        autoCheckDelay -= PAUSE_MS;
125
                    }
126
                    try {
127
                        Thread.sleep(PAUSE_MS);
128
                    } catch (InterruptedException e) {
129
                        e.printStackTrace();
130
                    }
131
                }
132
 
133
            };
134
        };
135
        searchThread.setName("ITextArticleWithCompletion thread");
136
        searchThread.setPriority(Thread.MIN_PRIORITY);
137
        searchThread.setDaemon(true);
138
        searchThread.start();
139
 
140
    }
141
 
142
    public void setPopupListEnabled(boolean b) {
143
        this.popup.setListEnabled(b);
144
    }
145
 
94 ilm 146
    private Where whereAdditionnal;
147
 
148
    public void setWhere(Where w) {
149
        this.whereAdditionnal = w;
150
    }
151
 
83 ilm 152
    public void setTextEditor(final JTextComponent atext) {
153
        if (atext == null) {
154
            throw new IllegalArgumentException("null textEditor");
155
        }
156
        this.text = atext;
157
        atext.getDocument().addDocumentListener(this);
158
        atext.addKeyListener(new KeyListener() {
159
 
160
            private boolean consume;
161
 
162
            public void keyPressed(KeyEvent e) {
163
                if (e.getKeyCode() == KeyEvent.VK_TAB) {
164
                    // Complete si exactement la valeur souhaitée
165
                    updateAutoCompletion(true);
166
                    e.consume();
94 ilm 167
 
83 ilm 168
                } else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
169
                    if (ITextArticleWithCompletion.this.popup.isShowing()) {
170
                        ITextArticleWithCompletion.this.popup.selectNext();
171
                        e.consume();
172
                    } else {
173
                        if (getSelectedRow() == null) {
174
                            // updateAutoCompletion();
175
                            showPopup();
176
                        }
177
                    }
178
 
179
                } else if (e.getKeyCode() == KeyEvent.VK_UP) {
180
                    if (ITextArticleWithCompletion.this.popup.isShowing()) {
181
                        ITextArticleWithCompletion.this.popup.selectPrevious();
182
                        e.consume();
183
                    }
184
 
185
                } else if (e.getKeyCode() == KeyEvent.VK_ENTER || e.getKeyCode() == KeyEvent.VK_TAB) {
186
                    if (ITextArticleWithCompletion.this.popup.isShowing()) {
187
                        ITextArticleWithCompletion.this.popup.validateSelection();
188
                        e.consume();
189
                    } else {
190
                        autoselectIfMatch = true;
191
                        e.consume();
192
                    }
193
                } else if (e.getKeyCode() == KeyEvent.VK_PAGE_DOWN) {
194
                    if (ITextArticleWithCompletion.this.popup.isShowing()) {
195
                        ITextArticleWithCompletion.this.popup.selectNextPage();
196
                        e.consume();
197
                    }
198
                } else if (e.getKeyCode() == KeyEvent.VK_PAGE_UP) {
199
                    if (ITextArticleWithCompletion.this.popup.isShowing()) {
200
                        ITextArticleWithCompletion.this.popup.selectPreviousPage();
201
                        e.consume();
202
                    }
203
                } else if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
204
                    if (ITextArticleWithCompletion.this.popup.isShowing()) {
205
                        hidePopup();
206
                    }
207
 
208
                }
209
 
210
                // else {
211
                // if (e.getKeyCode() != KeyEvent.VK_RIGHT && e.getKeyCode() !=
212
                // KeyEvent.VK_LEFT) {
213
                // fireSelectionId(-1);
214
                // }
215
                // }
216
                // Evite les bips
217
                if (ITextArticleWithCompletion.this.text.getDocument().getLength() == 0 && (e.getKeyCode() == KeyEvent.VK_DELETE || e.getKeyCode() == KeyEvent.VK_BACK_SPACE)) {
218
                    System.err.println("consume");
219
                    this.consume = true;
220
                    e.consume();
221
                }
222
 
223
            }
224
 
225
            public void keyReleased(KeyEvent e) {
226
            }
227
 
228
            public void keyTyped(KeyEvent e) {
229
                // Evite les bips
230
                if (this.consume) {
231
                    e.consume();
232
                    this.consume = false;
233
                }
234
            }
235
        });
236
        this.addComponentListener(new ComponentListener() {
237
            public void componentHidden(ComponentEvent e) {
238
            }
239
 
240
            public void componentMoved(ComponentEvent e) {
241
            }
242
 
243
            public void componentResized(ComponentEvent e) {
244
                // ajuste la taille min de la popup
245
                ITextArticleWithCompletion.this.popup.setMinWith(atext.getBounds().width);
246
            }
247
 
248
            public void componentShown(ComponentEvent e) {
249
            }
250
        });
251
        atext.addFocusListener(new FocusListener() {
252
            @Override
253
            public void focusGained(FocusEvent e) {
254
 
255
            }
256
 
257
            @Override
258
            public void focusLost(FocusEvent e) {
259
                hidePopup();
260
            }
261
        });
262
    }
263
 
264
    /**
265
     * Retourne une liste de IComboSelectionItem, qui sont les selections possibles pour le text
266
     * passé
267
     *
268
     * @throws SQLException
269
     */
270
    List<IComboSelectionItem> getPossibleValues(String aText) throws SQLException {
271
        List<IComboSelectionItem> result = new Vector<IComboSelectionItem>();
272
        if (aText.isEmpty()) {
273
            return result;
274
        }
275
        aText = aText.trim();
276
 
277
        if (aText.length() > 0) {
278
 
279
            List<SQLSelect> listSel = new ArrayList<SQLSelect>();
280
            // CODE ARTICLE = aText
281
            SQLSelect selMatchingCode = new SQLSelect();
282
            // selMatchingCode.addSelectStar(this.tableArticle);
283
            selMatchingCode.addSelect(this.tableArticle.getKey());
284
            selMatchingCode.addSelect(this.tableArticle.getField("CODE"));
285
            selMatchingCode.addSelect(this.tableArticle.getField("NOM"));
286
            selMatchingCode.addSelect(this.tableArticle.getField("CODE_BARRE"));
287
            Where wMatchingCode = new Where(this.tableArticle.getField("CODE"), "=", aText);
288
            wMatchingCode = wMatchingCode.or(new Where(this.tableArticle.getField("NOM"), "=", aText));
289
            wMatchingCode = wMatchingCode.or(new Where(this.tableArticle.getField("CODE_BARRE"), "=", aText));
94 ilm 290
            if (this.whereAdditionnal != null) {
291
                wMatchingCode = wMatchingCode.and(this.whereAdditionnal);
292
            }
83 ilm 293
            selMatchingCode.setWhere(wMatchingCode);
294
            listSel.add(selMatchingCode);
295
 
296
            // CODE ARTICLE LIKE %aText% with limit
297
            SQLSelect selContains = new SQLSelect();
298
            // selContains.addSelectStar(this.tableArticle);
299
            selContains.addSelect(this.tableArticle.getKey());
300
            selContains.addSelect(this.tableArticle.getField("CODE"));
301
            selContains.addSelect(this.tableArticle.getField("NOM"));
302
            selContains.addSelect(this.tableArticle.getField("CODE_BARRE"));
303
            Where wContains = new Where(this.tableArticle.getField("CODE"), "LIKE", "%" + aText + "%");
304
            wContains = wContains.or(new Where(this.tableArticle.getField("NOM"), "LIKE", "%" + aText + "%"));
305
            wContains = wContains.or(new Where(this.tableArticle.getField("CODE_BARRE"), "LIKE", "%" + aText + "%"));
94 ilm 306
            if (this.whereAdditionnal != null) {
307
                wContains = wContains.and(this.whereAdditionnal);
308
            }
83 ilm 309
            selContains.setWhere(wContains.and(wMatchingCode.not()));
310
            selContains.setLimit(SQL_RESULT_LIMIT);
311
            listSel.add(selContains);
312
 
313
            // CODE ARTICLE = aText
94 ilm 314
            final Where wNotSync = new Where(this.tableArticleFournisseur.getField("ID_ARTICLE"), "IS", (Object) null)
315
                    .or(new Where(this.tableArticleFournisseur.getField("ID_ARTICLE"), "=", this.tableArticleFournisseur.getUndefinedID()));
83 ilm 316
 
317
            SQLSelect selMatchingCodeF = new SQLSelect();
318
            // selMatchingCodeF.addSelectStar(this.tableArticleFournisseur);
319
            selMatchingCodeF.addSelect(this.tableArticleFournisseur.getKey());
320
            selMatchingCodeF.addSelect(this.tableArticleFournisseur.getField("CODE"));
321
            selMatchingCodeF.addSelect(this.tableArticleFournisseur.getField("NOM"));
322
            selMatchingCodeF.addSelect(this.tableArticleFournisseur.getField("CODE_BARRE"));
323
            Where wMatchingCodeF = new Where(this.tableArticleFournisseur.getField("CODE"), "=", aText);
324
            wMatchingCodeF = wMatchingCodeF.or(new Where(this.tableArticleFournisseur.getField("CODE_BARRE"), "=", aText));
325
            wMatchingCodeF = wMatchingCodeF.or(new Where(this.tableArticleFournisseur.getField("NOM"), "=", aText));
326
            selMatchingCodeF.setWhere(wMatchingCodeF.and(wNotSync));
327
            listSel.add(selMatchingCodeF);
328
 
329
            // CODE ARTICLE_FOURNISSEUR LIKE %aText% with limit
330
            SQLSelect selContainsCodeF = new SQLSelect();
331
            // selContainsCodeF.addSelectStar(this.tableArticleFournisseur);
332
            selContainsCodeF.addSelect(this.tableArticleFournisseur.getKey());
333
            selContainsCodeF.addSelect(this.tableArticleFournisseur.getField("CODE"));
334
            selContainsCodeF.addSelect(this.tableArticleFournisseur.getField("NOM"));
335
            selContainsCodeF.addSelect(this.tableArticleFournisseur.getField("CODE_BARRE"));
336
            Where wContainsCodeF = new Where(this.tableArticleFournisseur.getField("CODE"), "LIKE", "%" + aText + "%");
337
            wContainsCodeF = wContainsCodeF.or(new Where(this.tableArticleFournisseur.getField("CODE_BARRE"), "LIKE", "%" + aText + "%"));
338
            wContainsCodeF = wContainsCodeF.or(new Where(this.tableArticleFournisseur.getField("NOM"), "LIKE", "%" + aText + "%"));
339
            selContainsCodeF.setWhere(wContainsCodeF.and(wMatchingCodeF.not()).and(wNotSync));
340
            selContainsCodeF.setLimit(SQL_RESULT_LIMIT);
341
 
342
            listSel.add(selContainsCodeF);
343
 
344
            MultipleSQLSelectExecutor mult = new MultipleSQLSelectExecutor(this.tableArticle.getDBSystemRoot(), listSel);
345
 
346
            List<List<SQLRow>> resultList = mult.execute();
347
 
348
            for (List<SQLRow> list : resultList) {
349
 
350
                for (SQLRow sqlRow : list) {
351
 
352
                    StringBuffer buf = new StringBuffer();
353
                    if (sqlRow.getString("CODE_BARRE") != null && sqlRow.getString("CODE_BARRE").trim().length() > 0) {
354
                        buf.append(sqlRow.getString("CODE_BARRE") + " -- ");
355
                    }
356
                    buf.append(sqlRow.getString("CODE") + " -- ");
357
                    buf.append(sqlRow.getString("NOM"));
358
                    result.add(new IComboSelectionItem(sqlRow, buf.toString()));
359
                }
360
            }
361
 
362
        }
363
 
364
        return result;
365
    }
366
 
367
    private void updateAutoCompletion(boolean autoselectIfMatch) {
368
        this.autoselectIfMatch = autoselectIfMatch;
369
        this.autoCheckDelay = PAUSE_MS * 2;
370
        synchronized (searchStack) {
371
            this.searchStack.push(this.text.getText().trim());
372
        }
373
    }
374
 
375
    private void loadAutoCompletion() {
376
        if (!this.isCompletionEnabled() || this.isLoading) {
377
            return;
378
        }
379
        final String t;
380
        synchronized (searchStack) {
381
            if (this.searchStack.isEmpty()) {
382
                return;
383
            }
384
            t = this.searchStack.pop();
385
            this.searchStack.clear();
386
        }
387
 
388
        final SwingWorker2<List<IComboSelectionItem>, Object> worker = new SwingWorker2<List<IComboSelectionItem>, Object>() {
389
 
390
            @Override
391
            protected List<IComboSelectionItem> doInBackground() throws Exception {
392
                List<IComboSelectionItem> l = getPossibleValues(t); // Liste de IComboSelection
393
                return l;
394
            }
395
 
396
            @Override
397
            protected void done() {
398
                List<IComboSelectionItem> l;
399
                try {
400
                    l = get();
401
                } catch (Exception e) {
402
                    l = new ArrayList<IComboSelectionItem>(0);
403
                    e.printStackTrace();
404
                }
94 ilm 405
 
83 ilm 406
                // On cache la popup si le nombre de ligne change afin que sa taille soit correcte
407
                if (l.size() != model.getSize() && l.size() <= ITextWithCompletionPopUp.MAXROW) {
408
                    hidePopup();
409
                }
410
                // on vide le model
411
                model.removeAllElements();
412
                model.addAll(l);
413
 
414
                if (l.size() > 0) {
415
                    showPopup();
416
                } else {
417
                    hidePopup();
418
                }
419
                SQLRowAccessor newRow = selectedRow;
94 ilm 420
                IComboSelectionItem newSelectedItem = null;
83 ilm 421
                boolean found = false;
422
                for (Iterator<IComboSelectionItem> iter = l.iterator(); iter.hasNext();) {
423
                    IComboSelectionItem element = iter.next();
94 ilm 424
 
425
                    if ((element.getRow().getString("CODE_BARRE").toLowerCase().equals(t.toLowerCase()) || element.getRow().getString("CODE").toLowerCase().equals(t.toLowerCase()))
426
                            && autoselectIfMatch) {
83 ilm 427
                        newRow = element.getRow();
94 ilm 428
                        newSelectedItem = element;
83 ilm 429
                        hidePopup();
430
                        found = true;
431
                        break;
432
                    }
433
                }
434
                if (selectAuto && found && !CompareUtils.equals(newRow, selectedRow)) {
94 ilm 435
                    final IComboSelectionItem selectedItem = newSelectedItem;
83 ilm 436
                    SwingUtilities.invokeLater(new Runnable() {
437
                        public void run() {
94 ilm 438
                            itemSelected(selectedItem);
83 ilm 439
                        }
440
                    });
441
                }
442
                if (!found) {
443
                    selectedRow = null;
94 ilm 444
                    itemSelected(null);
83 ilm 445
                }
94 ilm 446
 
83 ilm 447
            }
448
        };
449
        worker.execute();
450
 
451
    }
452
 
453
    public synchronized void hidePopup() {
454
        this.popup.setVisible(false);
455
    }
456
 
457
    private synchronized void showPopup() {
458
        if (this.model.getSize() > 0) {
459
            if (this.popupInvoker.isShowing())
460
                this.popup.show(this.popupInvoker, 0, this.text.getBounds().height);
461
        }
462
    }
463
 
464
    public void changedUpdate(DocumentEvent e) {
465
        updateAutoCompletion(false);
466
        this.supp.firePropertyChange("value", null, this.getText());
467
    }
468
 
469
    public void insertUpdate(DocumentEvent e) {
470
        updateAutoCompletion(false);
471
        this.supp.firePropertyChange("value", null, this.getText());
472
    }
473
 
474
    public void removeUpdate(DocumentEvent e) {
475
        updateAutoCompletion(false);
476
        this.supp.firePropertyChange("value", null, this.getText());
477
    }
478
 
479
    public SQLRowAccessor getSelectedRow() {
480
        return this.selectedRow;
481
    }
482
 
483
    public void setSelectedRow(SQLRowAccessor row) {
484
        this.selectedRow = row;
485
    }
486
 
487
    private void clearText() {
488
        setText("");
489
    }
490
 
491
    public void setEditable(boolean b) {
492
        this.text.setEditable(b);
493
    }
494
 
495
    public void setFillWithField(String s) {
496
        this.fillWith = s;
497
    }
498
 
499
    public SQLField getFillWithField() {
500
        return this.tableArticle.getField(fillWith);
501
    }
502
 
503
    public void selectItem(IComboSelectionItem item) {
504
        if (!SwingUtilities.isEventDispatchThread()) {
505
            throw new IllegalStateException("Not in Swing!");
506
        }
507
        if (item != null) {
508
            if (this.fillWith != null) {
509
                // FIXME SQL request in Swing
510
                SQLRowAccessor row = item.getRow();
511
                this.setText(row.getObject(this.fillWith).toString());
512
            } else {
513
                this.setText(item.getLabel());
514
            }
515
        } else {
516
            this.clearText();
517
        }
518
        hidePopup();
519
    }
520
 
521
    public void setText(final String label) {
522
        if (!SwingUtilities.isEventDispatchThread()) {
523
            throw new IllegalStateException("Not in Swing!");
524
        }
525
        setCompletionEnabled(false);
526
        this.text.setText(label);
527
        if (label != null) {
528
            this.text.setCaretPosition(label.length());
529
        }
530
        this.text.repaint();
531
        setCompletionEnabled(true);
532
    }
533
 
534
    // Gestion des listeners de selection d'id
535
    public void addSelectionListener(SelectionRowListener l) {
536
        this.listeners.add(l);
537
    }
538
 
539
    public void removeSelectionListener(SelectionRowListener l) {
540
        this.listeners.remove(l);
541
    }
542
 
543
    private boolean isDispatching = false;
544
 
545
    private void fireSelectionRow(SQLRowAccessor row) {
546
        if (!this.isDispatching) {
94 ilm 547
 
83 ilm 548
            this.isDispatching = true;
549
            for (Iterator<SelectionRowListener> iter = this.listeners.iterator(); iter.hasNext();) {
550
                SelectionRowListener element = iter.next();
551
                element.rowSelected(row, this);
552
            }
553
            this.isDispatching = false;
554
        }
555
    }
556
 
557
    /**
558
     * @return Returns the completionEnabled.
559
     */
560
    boolean isCompletionEnabled() {
561
        return this.completionEnabled;
562
    }
563
 
564
    /**
565
     * @param completionEnabled The completionEnabled to set.
566
     */
567
    void setCompletionEnabled(boolean completionEnabled) {
568
        this.completionEnabled = completionEnabled;
569
    }
570
 
571
    public Object getText() {
572
        return this.text.getText();
573
    }
574
 
575
    /**
576
     * @param popupInvoker The popupInvoker to set.
577
     */
578
    public void setPopupInvoker(Component popupInvoker) {
579
        this.popupInvoker = popupInvoker;
580
    }
581
 
582
    public JTextComponent getTextComp() {
583
        return this.text;
584
    }
585
 
586
    public JComponent getComp() {
587
        return this;
588
    }
589
 
590
    public void setSelectionAutoEnabled(boolean b) {
591
        this.selectAuto = b;
592
    }
593
 
594
    public void setLimitedSize(int nbChar) {
595
        // rm previous ones
596
        final DocumentFilterList dfl = DocumentFilterList.get((AbstractDocument) this.text.getDocument());
597
        final Iterator<DocumentFilter> iter = dfl.getFilters().iterator();
598
        while (iter.hasNext()) {
599
            final DocumentFilter df = iter.next();
600
            if (df instanceof LimitedSizeDocumentFilter)
601
                iter.remove();
602
        }
603
        // add the new one
604
        DocumentFilterList.add((AbstractDocument) this.text.getDocument(), new LimitedSizeDocumentFilter(nbChar), FilterType.SIMPLE_FILTER);
605
    }
606
 
607
    @Override
608
    public void resetValue() {
609
        this.setText("");
610
    }
611
 
612
    @Override
613
    public void setValue(String val) {
614
        this.setText(val);
615
    }
616
 
617
    @Override
618
    public void addValueListener(PropertyChangeListener l) {
619
        this.supp.addPropertyChangeListener(l);
620
    }
621
 
622
    @Override
623
    public String getValue() {
624
        return (String) this.getText();
625
    }
626
 
627
    @Override
628
    public void rmValueListener(PropertyChangeListener l) {
629
        this.supp.removePropertyChangeListener(l);
630
    }
631
 
632
    @Override
633
    public void itemSelected(IComboSelectionItem item) {
634
        if (item == null) {
635
            fireSelectionRow(null);
636
        } else {
637
            final SQLRowAccessor row = item.getRow();
638
            if (this.isLoading) {
639
                this.rowToSelect = row;
640
 
641
            } else {
642
                if (!CompareUtils.equals(this.selectedRow, row)) {
643
                    this.setSelectedRow(row);
644
                    this.selectItem(item);
645
                    this.fireSelectionRow(row);
646
                }
647
            }
648
        }
649
    }
650
 
651
}