OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [javax/] [swing/] [JComboBox.java] - Blame information for rev 772

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 772 jeremybenn
/* JComboBox.java --
2
   Copyright (C) 2002, 2004, 2005, 2006,  Free Software Foundation, Inc.
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
 
39
package javax.swing;
40
 
41
import gnu.java.lang.CPStringBuilder;
42
 
43
import java.awt.ItemSelectable;
44
import java.awt.event.ActionEvent;
45
import java.awt.event.ActionListener;
46
import java.awt.event.ItemEvent;
47
import java.awt.event.ItemListener;
48
import java.awt.event.KeyEvent;
49
import java.beans.PropertyChangeEvent;
50
import java.beans.PropertyChangeListener;
51
import java.util.Vector;
52
 
53
import javax.accessibility.Accessible;
54
import javax.accessibility.AccessibleAction;
55
import javax.accessibility.AccessibleContext;
56
import javax.accessibility.AccessibleRole;
57
import javax.accessibility.AccessibleSelection;
58
import javax.swing.event.ListDataEvent;
59
import javax.swing.event.ListDataListener;
60
import javax.swing.event.PopupMenuEvent;
61
import javax.swing.event.PopupMenuListener;
62
import javax.swing.plaf.ComboBoxUI;
63
import javax.swing.plaf.ComponentUI;
64
import javax.swing.plaf.basic.ComboPopup;
65
 
66
/**
67
 * A component that allows a user to select any item in its list and
68
 * displays the selected item to the user. JComboBox also can show/hide a
69
 * popup menu containing its list of item whenever the mouse is pressed
70
 * over it.
71
 *
72
 * @author Andrew Selkirk
73
 * @author Olga Rodimina
74
 * @author Robert Schuster
75
 */
76
public class JComboBox extends JComponent implements ItemSelectable,
77
                                                     ListDataListener,
78
                                                     ActionListener,
79
                                                     Accessible
80
{
81
 
82
  private static final long serialVersionUID = 5654585963292734470L;
83
 
84
  /**
85
   * Classes implementing this interface are
86
   * responsible for matching key characters typed by the user with combo
87
   * box's items.
88
   */
89
  public static interface KeySelectionManager
90
  {
91
    int selectionForKey(char aKey, ComboBoxModel aModel);
92
  }
93
 
94
  /**
95
   * Maximum number of rows that should be visible by default  in the
96
   * JComboBox's popup
97
   */
98
  private static final int DEFAULT_MAXIMUM_ROW_COUNT = 8;
99
 
100
  /**
101
   * Data model used by JComboBox to keep track of its list data and currently
102
   * selected element in the list.
103
   */
104
  protected ComboBoxModel dataModel;
105
 
106
  /**
107
   * Renderer renders(paints) every object in the combo box list in its
108
   * associated list cell. This ListCellRenderer is used only when  this
109
   * JComboBox is uneditable.
110
   */
111
  protected ListCellRenderer renderer;
112
 
113
  /**
114
   * Editor that is responsible for editing an object in a combo box list.
115
   */
116
  protected ComboBoxEditor editor;
117
 
118
  /**
119
   * Number of rows that will be visible in the JComboBox's popup.
120
   */
121
  protected int maximumRowCount;
122
 
123
  /**
124
   * This field indicates if textfield of this JComboBox is editable or not.
125
   */
126
  protected boolean isEditable;
127
 
128
  /**
129
   * This field is reference to the current selection of the combo box.
130
   */
131
  protected Object selectedItemReminder;
132
 
133
  /**
134
   * keySelectionManager
135
   */
136
  protected KeySelectionManager keySelectionManager;
137
 
138
  /**
139
   * This actionCommand is used in ActionEvent that is fired to JComboBox's
140
   * ActionListeneres.
141
   */
142
  protected String actionCommand;
143
 
144
  /**
145
   * This property indicates if heavyweight popup or lightweight popup will be
146
   * used to diplay JComboBox's elements.
147
   */
148
  protected boolean lightWeightPopupEnabled;
149
 
150
  /**
151
   * The action taken when new item is selected in the JComboBox
152
   */
153
  private Action action;
154
 
155
  /**
156
   * since 1.4  If this field is set then comboBox's display area for the
157
   * selected item  will be set by default to this value.
158
   */
159
  private Object prototypeDisplayValue;
160
 
161
  /**
162
   * Constructs JComboBox object with specified data model for it.
163
   * <p>Note that the JComboBox will not change the value that
164
   * is preselected by your ComboBoxModel implementation.</p>
165
   *
166
   * @param model Data model that will be used by this JComboBox to keep track
167
   *        of its list of items.
168
   */
169
  public JComboBox(ComboBoxModel model)
170
  {
171
    setEditable(false);
172
    setEnabled(true);
173
    setMaximumRowCount(DEFAULT_MAXIMUM_ROW_COUNT);
174
    setModel(model);
175
    setActionCommand("comboBoxChanged");
176
 
177
    lightWeightPopupEnabled = true;
178
    isEditable = false;
179
 
180
    updateUI();
181
  }
182
 
183
  /**
184
   * Constructs JComboBox with specified list of items.
185
   *
186
   * @param itemArray array containing list of items for this JComboBox
187
   */
188
  public JComboBox(Object[] itemArray)
189
  {
190
    this(new DefaultComboBoxModel(itemArray));
191
 
192
    if (itemArray.length > 0)
193
      setSelectedIndex(0);
194
  }
195
 
196
  /**
197
   * Constructs JComboBox object with specified list of items.
198
   *
199
   * @param itemVector vector containing list of items for this JComboBox.
200
   */
201
  public JComboBox(Vector<?> itemVector)
202
  {
203
    this(new DefaultComboBoxModel(itemVector));
204
 
205
    if (itemVector.size() > 0)
206
      setSelectedIndex(0);
207
  }
208
 
209
  /**
210
   * Constructor. Creates new empty JComboBox. ComboBox's data model is set to
211
   * DefaultComboBoxModel.
212
   */
213
  public JComboBox()
214
  {
215
    this(new DefaultComboBoxModel());
216
  }
217
 
218
  /**
219
   * This method returns true JComboBox is editable and false otherwise
220
   *
221
   * @return boolean true if JComboBox is editable and false otherwise
222
   */
223
  public boolean isEditable()
224
  {
225
    return isEditable;
226
  }
227
 
228
  /*
229
   * This method adds ancestor listener to this JComboBox.
230
   */
231
  protected void installAncestorListener()
232
  {
233
    /* FIXME: Need to implement.
234
     *
235
     * Need to add ancestor listener to this JComboBox. This listener
236
     * should close combo box's popup list of items whenever it
237
     * receives an AncestorEvent.
238
     */
239
  }
240
 
241
  /**
242
   * Set the "UI" property of the combo box, which is a look and feel class
243
   * responsible for handling comboBox's input events and painting it.
244
   *
245
   * @param ui The new "UI" property
246
   */
247
  public void setUI(ComboBoxUI ui)
248
  {
249
    super.setUI(ui);
250
  }
251
 
252
  /**
253
   * This method sets this comboBox's UI to the UIManager's default for the
254
   * current look and feel.
255
   */
256
  public void updateUI()
257
  {
258
    setUI((ComboBoxUI) UIManager.getUI(this));
259
  }
260
 
261
  /**
262
   * This method returns the String identifier for the UI class to the used
263
   * with the JComboBox.
264
   *
265
   * @return The String identifier for the UI class.
266
   */
267
  public String getUIClassID()
268
  {
269
    return "ComboBoxUI";
270
  }
271
 
272
  /**
273
   * This method returns the UI used to display the JComboBox.
274
   *
275
   * @return The UI used to display the JComboBox.
276
   */
277
  public ComboBoxUI getUI()
278
  {
279
    return (ComboBoxUI) ui;
280
  }
281
 
282
  /**
283
   * Set the data model for this JComboBox. This un-registers all  listeners
284
   * associated with the current model, and re-registers them with the new
285
   * model.
286
   *
287
   * @param newDataModel The new data model for this JComboBox
288
   */
289
  public void setModel(ComboBoxModel newDataModel)
290
  {
291
    // dataModel is null if it this method is called from inside the constructors.
292
    if (dataModel != null)
293
      {
294
        // Prevents unneccessary updates.
295
        if (dataModel == newDataModel)
296
          return;
297
 
298
        // Removes itself (as DataListener) from the to-be-replaced model.
299
        dataModel.removeListDataListener(this);
300
      }
301
 
302
    /* Adds itself as a DataListener to the new model.
303
     * It is intentioned that this operation will fail with a NullPointerException if the
304
     * caller delivered a null argument.
305
     */
306
    newDataModel.addListDataListener(this);
307
 
308
    // Stores old data model for event notification.
309
    ComboBoxModel oldDataModel = dataModel;
310
    dataModel = newDataModel;
311
    selectedItemReminder = newDataModel.getSelectedItem();
312
 
313
    // Notifies the listeners of the model change.
314
    firePropertyChange("model", oldDataModel, dataModel);
315
  }
316
 
317
  /**
318
   * This method returns data model for this comboBox.
319
   *
320
   * @return ComboBoxModel containing items for this combo box.
321
   */
322
  public ComboBoxModel getModel()
323
  {
324
    return dataModel;
325
  }
326
 
327
  /**
328
   * This method sets JComboBox's popup to be either lightweight or
329
   * heavyweight. If 'enabled' is true then lightweight popup is used and
330
   * heavyweight otherwise. By default lightweight popup is used to display
331
   * this JComboBox's elements.
332
   *
333
   * @param enabled indicates if lightweight popup or heavyweight popup should
334
   *        be used to display JComboBox's elements.
335
   */
336
  public void setLightWeightPopupEnabled(boolean enabled)
337
  {
338
    lightWeightPopupEnabled = enabled;
339
  }
340
 
341
  /**
342
   * This method returns whether popup menu that is used to display list of
343
   * combo box's item is lightWeight or not.
344
   *
345
   * @return boolean true if popup menu is lightweight and false otherwise.
346
   */
347
  public boolean isLightWeightPopupEnabled()
348
  {
349
    return lightWeightPopupEnabled;
350
  }
351
 
352
  /**
353
   * This method sets editability of the combo box. If combo box  is editable
354
   * the user can choose component from the combo box list by typing
355
   * component's name in the editor(JTextfield by default).  Otherwise if not
356
   * editable, the user should use the list to choose   the component. This
357
   * method fires PropertyChangeEvents to JComboBox's registered
358
   * PropertyChangeListeners to indicate that 'editable' property of the
359
   * JComboBox has changed.
360
   *
361
   * @param editable indicates if the JComboBox's textfield should be editable
362
   *        or not.
363
   */
364
  public void setEditable(boolean editable)
365
  {
366
    if (isEditable != editable)
367
      {
368
        isEditable = editable;
369
        firePropertyChange("editable", !isEditable, isEditable);
370
      }
371
  }
372
 
373
  /**
374
   * Sets number of rows that should be visible in this JComboBox's popup. If
375
   * this JComboBox's popup has more elements that maximum number or rows
376
   * then popup will have a scroll pane to allow users to view other
377
   * elements.
378
   *
379
   * @param rowCount number of rows that will be visible in JComboBox's popup.
380
   */
381
  public void setMaximumRowCount(int rowCount)
382
  {
383
    if (maximumRowCount != rowCount)
384
      {
385
        int oldMaximumRowCount = maximumRowCount;
386
        maximumRowCount = rowCount;
387
        firePropertyChange("maximumRowCount", oldMaximumRowCount,
388
                           maximumRowCount);
389
      }
390
  }
391
 
392
  /**
393
   * This method returns number of rows visible in the JComboBox's list of
394
   * items.
395
   *
396
   * @return int maximun number of visible rows in the JComboBox's list.
397
   */
398
  public int getMaximumRowCount()
399
  {
400
    return maximumRowCount;
401
  }
402
 
403
  /**
404
   * This method sets cell renderer for this JComboBox that will be used to
405
   * paint combo box's items. The Renderer should only be used only when
406
   * JComboBox is not editable.  In the case when JComboBox is editable  the
407
   * editor must be used.  This method also fires PropertyChangeEvent when
408
   * cellRendered for this JComboBox has changed.
409
   *
410
   * @param aRenderer cell renderer that will be used by this JComboBox to
411
   *        paint its elements.
412
   */
413
  public void setRenderer(ListCellRenderer aRenderer)
414
  {
415
    if (renderer != aRenderer)
416
      {
417
        ListCellRenderer oldRenderer = renderer;
418
        renderer = aRenderer;
419
        firePropertyChange("renderer", oldRenderer, renderer);
420
      }
421
  }
422
 
423
  /**
424
   * This method returns renderer responsible for rendering selected item in
425
   * the combo box
426
   *
427
   * @return ListCellRenderer
428
   */
429
  public ListCellRenderer getRenderer()
430
  {
431
    return renderer;
432
  }
433
 
434
  /**
435
   * Sets editor for this JComboBox
436
   *
437
   * @param newEditor ComboBoxEditor for this JComboBox. This method fires
438
   *        PropertyChangeEvent when 'editor' property is changed.
439
   */
440
  public void setEditor(ComboBoxEditor newEditor)
441
  {
442
    if (editor == newEditor)
443
      return;
444
 
445
    if (editor != null)
446
      editor.removeActionListener(this);
447
 
448
    ComboBoxEditor oldEditor = editor;
449
    editor = newEditor;
450
 
451
    if (editor != null)
452
      editor.addActionListener(this);
453
 
454
    firePropertyChange("editor", oldEditor, editor);
455
  }
456
 
457
  /**
458
   * Returns editor component that is responsible for displaying/editing
459
   * selected item in the combo box.
460
   *
461
   * @return ComboBoxEditor
462
   */
463
  public ComboBoxEditor getEditor()
464
  {
465
    return editor;
466
  }
467
 
468
  /**
469
   * Forces combo box to select given item
470
   *
471
   * @param item element in the combo box to select.
472
   */
473
  public void setSelectedItem(Object item)
474
  {
475
    dataModel.setSelectedItem(item);
476
    fireActionEvent();
477
  }
478
 
479
  /**
480
   * Returns currently selected item in the combo box.
481
   * The result may be <code>null</code> to indicate that nothing is
482
   * currently selected.
483
   *
484
   * @return element that is currently selected in this combo box.
485
   */
486
  public Object getSelectedItem()
487
  {
488
    return dataModel.getSelectedItem();
489
  }
490
 
491
  /**
492
   * Forces JComboBox to select component located in the given index in the
493
   * combo box.
494
   * <p>If the index is below -1 or exceeds the upper bound an
495
   * <code>IllegalArgumentException</code> is thrown.<p/>
496
   * <p>If the index is -1 then no item gets selected.</p>
497
   *
498
   * @param index index specifying location of the component that  should be
499
   *        selected.
500
   */
501
  public void setSelectedIndex(int index)
502
  {
503
        if (index < -1 || index >= dataModel.getSize())
504
      // Fails because index is out of bounds.
505
      throw new IllegalArgumentException("illegal index: " + index);
506
    else
507
       // Selects the item at the given index or clears the selection if the
508
       // index value is -1.
509
      setSelectedItem((index == -1) ? null : dataModel.getElementAt(index));
510
  }
511
 
512
  /**
513
   * Returns index of the item that is currently selected in the combo box. If
514
   * no item is currently selected, then -1 is returned.
515
   * <p>
516
   * Note: For performance reasons you should minimize invocation of this
517
   * method. If the data model is not an instance of
518
   * <code>DefaultComboBoxModel</code> the complexity is O(n) where n is the
519
   * number of elements in the combo box.
520
   * </p>
521
   *
522
   * @return int Index specifying location of the currently selected item in the
523
   *         combo box or -1 if nothing is selected in the combo box.
524
   */
525
  public int getSelectedIndex()
526
  {
527
    Object selectedItem = getSelectedItem();
528
 
529
    if (selectedItem != null)
530
      {
531
        if (dataModel instanceof DefaultComboBoxModel)
532
          // Uses special method of DefaultComboBoxModel to retrieve the index.
533
          return ((DefaultComboBoxModel) dataModel).getIndexOf(selectedItem);
534
        else
535
          {
536
            // Iterates over all items to retrieve the index.
537
            int size = dataModel.getSize();
538
 
539
            for (int i = 0; i < size; i++)
540
              {
541
                Object o = dataModel.getElementAt(i);
542
 
543
                // XXX: Is special handling of ComparableS neccessary?
544
                if ((selectedItem != null) ? selectedItem.equals(o) : o == null)
545
                  return i;
546
              }
547
          }
548
      }
549
 
550
    // returns that no item is currently selected
551
    return -1;
552
  }
553
 
554
  /**
555
   * Returns an object that is used as the display value when calculating the
556
   * preferred size for the combo box.  This value is, of course, never
557
   * displayed anywhere.
558
   *
559
   * @return The prototype display value (possibly <code>null</code>).
560
   *
561
   * @since 1.4
562
   * @see #setPrototypeDisplayValue(Object)
563
   */
564
  public Object getPrototypeDisplayValue()
565
  {
566
    return prototypeDisplayValue;
567
  }
568
 
569
  /**
570
   * Sets the object that is assumed to be the displayed item when calculating
571
   * the preferred size for the combo box.  A {@link PropertyChangeEvent} (with
572
   * the name <code>prototypeDisplayValue</code>) is sent to all registered
573
   * listeners.
574
   *
575
   * @param value  the new value (<code>null</code> permitted).
576
   *
577
   * @since 1.4
578
   * @see #getPrototypeDisplayValue()
579
   */
580
  public void setPrototypeDisplayValue(Object value)
581
  {
582
    Object oldValue = prototypeDisplayValue;
583
    prototypeDisplayValue = value;
584
    firePropertyChange("prototypeDisplayValue", oldValue, value);
585
  }
586
 
587
  /**
588
   * This method adds given element to this JComboBox.
589
   * <p>A <code>RuntimeException</code> is thrown if the data model is not
590
   * an instance of {@link MutableComboBoxModel}.</p>
591
   *
592
   * @param element element to add
593
   */
594
  public void addItem(Object element)
595
  {
596
        if (dataModel instanceof MutableComboBoxModel)
597
      ((MutableComboBoxModel) dataModel).addElement(element);
598
    else
599
      throw new RuntimeException("Unable to add the item because the data "
600
                                 + "model it is not an instance of "
601
                                 + "MutableComboBoxModel.");
602
  }
603
 
604
  /**
605
   * Inserts given element at the specified index to this JComboBox.
606
   * <p>A <code>RuntimeException</code> is thrown if the data model is not
607
   * an instance of {@link MutableComboBoxModel}.</p>
608
   *
609
   * @param element element to insert
610
   * @param index position where to insert the element
611
   */
612
  public void insertItemAt(Object element, int index)
613
  {
614
        if (dataModel instanceof MutableComboBoxModel)
615
      ((MutableComboBoxModel) dataModel).insertElementAt(element, index);
616
    else
617
      throw new RuntimeException("Unable to insert the item because the data "
618
                                 + "model it is not an instance of "
619
                                 + "MutableComboBoxModel.");
620
  }
621
 
622
  /**
623
   * This method removes given element from this JComboBox.
624
   * <p>A <code>RuntimeException</code> is thrown if the data model is not
625
   * an instance of {@link MutableComboBoxModel}.</p>
626
   *
627
   * @param element element to remove
628
   */
629
  public void removeItem(Object element)
630
  {
631
        if (dataModel instanceof MutableComboBoxModel)
632
      ((MutableComboBoxModel) dataModel).removeElement(element);
633
    else
634
      throw new RuntimeException("Unable to remove the item because the data "
635
                                 + "model it is not an instance of "
636
                                 + "MutableComboBoxModel.");
637
  }
638
 
639
  /**
640
   * This method remove element location in the specified index in the
641
   * JComboBox.
642
   * <p>A <code>RuntimeException</code> is thrown if the data model is not
643
   * an instance of {@link MutableComboBoxModel}.</p>
644
   *
645
   * @param index index specifying position of the element to remove
646
   */
647
  public void removeItemAt(int index)
648
  {
649
    if (dataModel instanceof MutableComboBoxModel)
650
      ((MutableComboBoxModel) dataModel).removeElementAt(index);
651
    else
652
      throw new RuntimeException("Unable to remove the item because the data "
653
                                 + "model it is not an instance of "
654
                                 + "MutableComboBoxModel.");
655
  }
656
 
657
  /**
658
   * This method removes all elements from this JComboBox.
659
   * <p>
660
   * A <code>RuntimeException</code> is thrown if the data model is not an
661
   * instance of {@link MutableComboBoxModel}.
662
   * </p>
663
   */
664
  public void removeAllItems()
665
  {
666
    if (dataModel instanceof DefaultComboBoxModel)
667
      // Uses special method if we have a DefaultComboBoxModel.
668
      ((DefaultComboBoxModel) dataModel).removeAllElements();
669
    else if (dataModel instanceof MutableComboBoxModel)
670
      {
671
        // Iterates over all items and removes each.
672
        MutableComboBoxModel mcbm = (MutableComboBoxModel) dataModel;
673
 
674
         // We intentionally remove the items backwards to support models which
675
         // shift their content to the beginning (e.g. linked lists)
676
        for (int i = mcbm.getSize() - 1; i >= 0; i--)
677
          mcbm.removeElementAt(i);
678
      }
679
    else
680
      throw new RuntimeException("Unable to remove the items because the data "
681
                                 + "model it is not an instance of "
682
                                 + "MutableComboBoxModel.");
683
  }
684
 
685
  /**
686
   * This method displays popup with list of combo box's items on the screen
687
   */
688
  public void showPopup()
689
  {
690
    setPopupVisible(true);
691
  }
692
 
693
  /**
694
   * This method hides popup containing list of combo box's items
695
   */
696
  public void hidePopup()
697
  {
698
    setPopupVisible(false);
699
  }
700
 
701
  /**
702
   * This method either displayes or hides the popup containing  list of combo
703
   * box's items.
704
   *
705
   * @param visible show popup if 'visible' is true and hide it otherwise
706
   */
707
  public void setPopupVisible(boolean visible)
708
  {
709
    getUI().setPopupVisible(this, visible);
710
  }
711
 
712
  /**
713
   * Checks if popup is currently visible on the screen.
714
   *
715
   * @return boolean true if popup is visible and false otherwise
716
   */
717
  public boolean isPopupVisible()
718
  {
719
    return getUI().isPopupVisible(this);
720
  }
721
 
722
  /**
723
   * This method sets actionCommand to the specified string. ActionEvent fired
724
   * to this JComboBox  registered ActionListeners will contain this
725
   * actionCommand.
726
   *
727
   * @param aCommand new action command for the JComboBox's ActionEvent
728
   */
729
  public void setActionCommand(String aCommand)
730
  {
731
    actionCommand = aCommand;
732
  }
733
 
734
  /**
735
   * Returns actionCommand associated with the ActionEvent fired by the
736
   * JComboBox to its registered ActionListeners.
737
   *
738
   * @return String actionCommand for the ActionEvent
739
   */
740
  public String getActionCommand()
741
  {
742
    return actionCommand;
743
  }
744
 
745
  /**
746
   * setAction
747
   *
748
   * @param a action to set
749
   */
750
  public void setAction(Action a)
751
  {
752
    Action old = action;
753
    action = a;
754
    configurePropertiesFromAction(action);
755
    if (action != null)
756
      // FIXME: remove from old action and add to new action
757
      // PropertyChangeListener to listen to changes in the action
758
      addActionListener(action);
759
  }
760
 
761
  /**
762
   * This method returns Action that is invoked when selected item is changed
763
   * in the JComboBox.
764
   *
765
   * @return Action
766
   */
767
  public Action getAction()
768
  {
769
    return action;
770
  }
771
 
772
  /**
773
   * Configure properties of the JComboBox by reading properties of specified
774
   * action. This method always sets the comboBox's "enabled" property to the
775
   * value of the Action's "enabled" property.
776
   *
777
   * @param a An Action to configure the combo box from
778
   */
779
  protected void configurePropertiesFromAction(Action a)
780
  {
781
    if (a == null)
782
      {
783
        setEnabled(true);
784
        setToolTipText(null);
785
      }
786
    else
787
      {
788
        setEnabled(a.isEnabled());
789
        setToolTipText((String) (a.getValue(Action.SHORT_DESCRIPTION)));
790
      }
791
  }
792
 
793
  /**
794
   * Creates PropertyChangeListener to listen for the changes in comboBox's
795
   * action properties.
796
   *
797
   * @param action action to listen to for property changes
798
   *
799
   * @return a PropertyChangeListener that listens to changes in
800
   *         action properties.
801
   */
802
  protected PropertyChangeListener createActionPropertyChangeListener(Action action)
803
  {
804
    return new PropertyChangeListener()
805
      {
806
        public void propertyChange(PropertyChangeEvent e)
807
        {
808
          Action act = (Action) (e.getSource());
809
          configurePropertiesFromAction(act);
810
        }
811
      };
812
  }
813
 
814
  /**
815
   * This method fires ItemEvent to this JComboBox's registered ItemListeners.
816
   * This method is invoked when currently selected item in this combo box
817
   * has changed.
818
   *
819
   * @param e the ItemEvent describing the change in the combo box's
820
   *        selection.
821
   */
822
  protected void fireItemStateChanged(ItemEvent e)
823
  {
824
    ItemListener[] ll = getItemListeners();
825
 
826
    for (int i = 0; i < ll.length; i++)
827
      ll[i].itemStateChanged(e);
828
  }
829
 
830
  /**
831
   * This method fires ActionEvent to this JComboBox's registered
832
   * ActionListeners. This method is invoked when user explicitly changes
833
   * currently selected item.
834
   */
835
  protected void fireActionEvent()
836
  {
837
    ActionListener[] ll = getActionListeners();
838
 
839
    for (int i = 0; i < ll.length; i++)
840
      ll[i].actionPerformed(new ActionEvent(this,
841
                                            ActionEvent.ACTION_PERFORMED,
842
                                            actionCommand));
843
  }
844
 
845
  /**
846
   * Fires a popupMenuCanceled() event to all <code>PopupMenuListeners</code>.
847
   *
848
   * Note: This method is intended for use by plaf classes only.
849
   */
850
  public void firePopupMenuCanceled()
851
  {
852
    PopupMenuListener[] listeners = getPopupMenuListeners();
853
    PopupMenuEvent e = new PopupMenuEvent(this);
854
    for (int i = 0; i < listeners.length; i++)
855
      listeners[i].popupMenuCanceled(e);
856
  }
857
 
858
  /**
859
   * Fires a popupMenuWillBecomeInvisible() event to all
860
   * <code>PopupMenuListeners</code>.
861
   *
862
   * Note: This method is intended for use by plaf classes only.
863
   */
864
  public void firePopupMenuWillBecomeInvisible()
865
  {
866
    PopupMenuListener[] listeners = getPopupMenuListeners();
867
    PopupMenuEvent e = new PopupMenuEvent(this);
868
    for (int i = 0; i < listeners.length; i++)
869
      listeners[i].popupMenuWillBecomeInvisible(e);
870
  }
871
 
872
  /**
873
   * Fires a popupMenuWillBecomeVisible() event to all
874
   * <code>PopupMenuListeners</code>.
875
   *
876
   * Note: This method is intended for use by plaf classes only.
877
   */
878
  public void firePopupMenuWillBecomeVisible()
879
  {
880
    PopupMenuListener[] listeners = getPopupMenuListeners();
881
    PopupMenuEvent e = new PopupMenuEvent(this);
882
    for (int i = 0; i < listeners.length; i++)
883
      listeners[i].popupMenuWillBecomeVisible(e);
884
  }
885
 
886
  /**
887
   * This method is invoked whenever selected item changes in the combo box's
888
   * data model. It fires ItemEvent and ActionEvent to all registered
889
   * ComboBox's ItemListeners and ActionListeners respectively, indicating
890
   * the change.
891
   */
892
  protected void selectedItemChanged()
893
  {
894
    // Fire ItemEvent to indicated that previously selected item is now
895
    // deselected
896
    if (selectedItemReminder != null)
897
      fireItemStateChanged(new ItemEvent(this, ItemEvent.ITEM_STATE_CHANGED,
898
                                         selectedItemReminder,
899
                                         ItemEvent.DESELECTED));
900
 
901
    // Fire ItemEvent to indicate that new item is selected
902
    Object newSelection = getSelectedItem();
903
    if (newSelection != null)
904
      fireItemStateChanged(new ItemEvent(this, ItemEvent.ITEM_STATE_CHANGED,
905
                                         newSelection, ItemEvent.SELECTED));
906
 
907
    // Fire Action Event to JComboBox's registered listeners
908
    fireActionEvent();
909
 
910
    selectedItemReminder = newSelection;
911
  }
912
 
913
  /**
914
   * Returns Object array of size 1 containing currently selected element in
915
   * the JComboBox.
916
   *
917
   * @return Object[] Object array of size 1 containing currently selected
918
   *         element in the JComboBox.
919
   */
920
  public Object[] getSelectedObjects()
921
  {
922
    return new Object[] { getSelectedItem() };
923
  }
924
 
925
  /**
926
   * This method handles actionEvents fired by the ComboBoxEditor. It changes
927
   * this JComboBox's selection to the new value currently in the editor and
928
   * hides list of combo box items.
929
   *
930
   * @param e the ActionEvent
931
   */
932
  public void actionPerformed(ActionEvent e)
933
  {
934
    setSelectedItem(getEditor().getItem());
935
    setPopupVisible(false);
936
  }
937
 
938
  /**
939
   * This method selects item in this combo box that matches specified
940
   * specified keyChar and returns true if such item is found. Otherwise
941
   * false is returned.
942
   *
943
   * @param keyChar character indicating which item in the combo box should be
944
   *        selected.
945
   *
946
   * @return boolean true if item corresponding to the specified keyChar
947
   *         exists in the combo box. Otherwise false is returned.
948
   */
949
  public boolean selectWithKeyChar(char keyChar)
950
  {
951
    if (keySelectionManager == null)
952
      {
953
        keySelectionManager = createDefaultKeySelectionManager();
954
      }
955
 
956
    int index = keySelectionManager.selectionForKey(keyChar, getModel());
957
    boolean retVal = false;
958
    if (index >= 0)
959
      {
960
        setSelectedIndex(index);
961
        retVal = true;
962
      }
963
    return retVal;
964
  }
965
 
966
  /**
967
   * The part of implementation of ListDataListener interface. This method is
968
   * invoked when some items where added to the JComboBox's data model.
969
   *
970
   * @param event ListDataEvent describing the change
971
   */
972
  public void intervalAdded(ListDataEvent event)
973
  {
974
    // FIXME: Need to implement
975
    repaint();
976
  }
977
 
978
  /**
979
   * The part of implementation of ListDataListener interface. This method is
980
   * invoked when some items where removed from the JComboBox's data model.
981
   *
982
   * @param event ListDataEvent describing the change.
983
   */
984
  public void intervalRemoved(ListDataEvent event)
985
  {
986
    // FIXME: Need to implement
987
    repaint();
988
  }
989
 
990
  /**
991
   * The part of implementation of ListDataListener interface. This method is
992
   * invoked when contents of the JComboBox's  data model changed.
993
   *
994
   * @param event ListDataEvent describing the change
995
   */
996
  public void contentsChanged(ListDataEvent event)
997
  {
998
    // if first and last index of the given ListDataEvent are both -1,
999
    // then it indicates that selected item in the combo box data model
1000
    // have changed.
1001
    if (event.getIndex0() == -1 && event.getIndex1() == -1)
1002
      selectedItemChanged();
1003
  }
1004
 
1005
  /**
1006
   * This method disables or enables JComboBox. If the JComboBox is enabled,
1007
   * then user is able to make item choice, otherwise if JComboBox is
1008
   * disabled then user is not able to make a selection.
1009
   *
1010
   * @param enabled if 'enabled' is true then enable JComboBox and disable it
1011
   */
1012
  public void setEnabled(boolean enabled)
1013
  {
1014
    boolean oldEnabled = super.isEnabled();
1015
    if (enabled != oldEnabled)
1016
      {
1017
        super.setEnabled(enabled);
1018
        firePropertyChange("enabled", oldEnabled, enabled);
1019
      }
1020
  }
1021
 
1022
  /**
1023
   * This method initializes specified ComboBoxEditor to display given item.
1024
   *
1025
   * @param anEditor ComboBoxEditor to initialize
1026
   * @param anItem Item that should displayed in the specified editor
1027
   */
1028
  public void configureEditor(ComboBoxEditor anEditor, Object anItem)
1029
  {
1030
    anEditor.setItem(anItem);
1031
  }
1032
 
1033
  /**
1034
   * This method is fired whenever a key is pressed with the combo box
1035
   * in focus
1036
   *
1037
   * @param e The KeyEvent indicating which key was pressed.
1038
   */
1039
  public void processKeyEvent(KeyEvent e)
1040
  {
1041
    if (e.getKeyCode() == KeyEvent.VK_TAB)
1042
      setPopupVisible(false);
1043
    else
1044
      super.processKeyEvent(e);
1045
  }
1046
 
1047
  /**
1048
   * setKeySelectionManager
1049
   *
1050
   * @param aManager
1051
   */
1052
  public void setKeySelectionManager(KeySelectionManager aManager)
1053
  {
1054
    keySelectionManager = aManager;
1055
  }
1056
 
1057
  /**
1058
   * getKeySelectionManager
1059
   *
1060
   * @return JComboBox.KeySelectionManager
1061
   */
1062
  public KeySelectionManager getKeySelectionManager()
1063
  {
1064
    return keySelectionManager;
1065
  }
1066
 
1067
  /**
1068
   * This method returns number of elements in this JComboBox
1069
   *
1070
   * @return int number of elements in this JComboBox
1071
   */
1072
  public int getItemCount()
1073
  {
1074
    return dataModel.getSize();
1075
  }
1076
 
1077
  /**
1078
   * Returns elements located in the combo box at the given index.
1079
   *
1080
   * @param index index specifying location of the component to  return.
1081
   *
1082
   * @return component in the combo box that is located in  the given index.
1083
   */
1084
  public Object getItemAt(int index)
1085
  {
1086
    return dataModel.getElementAt(index);
1087
  }
1088
 
1089
  /**
1090
   * createDefaultKeySelectionManager
1091
   *
1092
   * @return KeySelectionManager
1093
   */
1094
  protected KeySelectionManager createDefaultKeySelectionManager()
1095
  {
1096
    return new DefaultKeySelectionManager();
1097
  }
1098
 
1099
  /**
1100
   * Returns an implementation-dependent string describing the attributes of
1101
   * this <code>JComboBox</code>.
1102
   *
1103
   * @return A string describing the attributes of this <code>JComboBox</code>
1104
   *         (never <code>null</code>).
1105
   */
1106
  protected String paramString()
1107
  {
1108
    String superParamStr = super.paramString();
1109
    CPStringBuilder sb = new CPStringBuilder();
1110
    sb.append(",isEditable=").append(isEditable());
1111
    sb.append(",lightWeightPopupEnabled=").append(isLightWeightPopupEnabled());
1112
    sb.append(",maximumRowCount=").append(getMaximumRowCount());
1113
 
1114
    sb.append(",selectedItemReminder=");
1115
    if (selectedItemReminder != null)
1116
      sb.append(selectedItemReminder);
1117
    return superParamStr + sb.toString();
1118
  }
1119
 
1120
  /**
1121
   * Returns the object that provides accessibility features for this
1122
   * <code>JComboBox</code> component.
1123
   *
1124
   * @return The accessible context (an instance of
1125
   *         {@link AccessibleJComboBox}).
1126
   */
1127
  public AccessibleContext getAccessibleContext()
1128
  {
1129
    if (accessibleContext == null)
1130
      accessibleContext = new AccessibleJComboBox();
1131
 
1132
    return accessibleContext;
1133
  }
1134
 
1135
  /**
1136
   * This methods adds specified ActionListener to this JComboBox.
1137
   *
1138
   * @param listener to add
1139
   */
1140
  public void addActionListener(ActionListener listener)
1141
  {
1142
    listenerList.add(ActionListener.class, listener);
1143
  }
1144
 
1145
  /**
1146
   * This method removes specified ActionListener from this JComboBox.
1147
   *
1148
   * @param listener ActionListener
1149
   */
1150
  public void removeActionListener(ActionListener listener)
1151
  {
1152
    listenerList.remove(ActionListener.class, listener);
1153
  }
1154
 
1155
  /**
1156
   * This method returns array of ActionListeners that are registered with
1157
   * this JComboBox.
1158
   *
1159
   * @since 1.4
1160
   */
1161
  public ActionListener[] getActionListeners()
1162
  {
1163
    return (ActionListener[]) getListeners(ActionListener.class);
1164
  }
1165
 
1166
  /**
1167
   * This method registers given ItemListener with this JComboBox
1168
   *
1169
   * @param listener to remove
1170
   */
1171
  public void addItemListener(ItemListener listener)
1172
  {
1173
    listenerList.add(ItemListener.class, listener);
1174
  }
1175
 
1176
  /**
1177
   * This method unregisters given ItemListener from this JComboBox
1178
   *
1179
   * @param listener to remove
1180
   */
1181
  public void removeItemListener(ItemListener listener)
1182
  {
1183
    listenerList.remove(ItemListener.class, listener);
1184
  }
1185
 
1186
  /**
1187
   * This method returns array of ItemListeners that are registered with this
1188
   * JComboBox.
1189
   *
1190
   * @since 1.4
1191
   */
1192
  public ItemListener[] getItemListeners()
1193
  {
1194
    return (ItemListener[]) getListeners(ItemListener.class);
1195
  }
1196
 
1197
  /**
1198
   * Adds PopupMenuListener to combo box to listen to the events fired by the
1199
   * combo box's popup menu containing its list of items
1200
   *
1201
   * @param listener to add
1202
   */
1203
  public void addPopupMenuListener(PopupMenuListener listener)
1204
  {
1205
    listenerList.add(PopupMenuListener.class, listener);
1206
  }
1207
 
1208
  /**
1209
   * Removes PopupMenuListener to combo box to listen to the events fired by
1210
   * the combo box's popup menu containing its list of items
1211
   *
1212
   * @param listener to add
1213
   */
1214
  public void removePopupMenuListener(PopupMenuListener listener)
1215
  {
1216
    listenerList.remove(PopupMenuListener.class, listener);
1217
  }
1218
 
1219
  /**
1220
   * Returns array of PopupMenuListeners that are registered with  combo box.
1221
   */
1222
  public PopupMenuListener[] getPopupMenuListeners()
1223
  {
1224
    return (PopupMenuListener[]) getListeners(PopupMenuListener.class);
1225
  }
1226
 
1227
  /**
1228
   * Accessibility support for <code>JComboBox</code>.
1229
   */
1230
  protected class AccessibleJComboBox extends AccessibleJComponent
1231
    implements AccessibleAction, AccessibleSelection
1232
  {
1233
    private static final long serialVersionUID = 8217828307256675666L;
1234
 
1235
    /**
1236
     * @specnote This constructor was protected in 1.4, but made public
1237
     * in 1.5.
1238
     */
1239
    public AccessibleJComboBox()
1240
    {
1241
      // Nothing to do here.
1242
    }
1243
 
1244
    /**
1245
     * Returns the number of accessible children of this object. The
1246
     * implementation of AccessibleJComboBox delegates this call to the UI
1247
     * of the associated JComboBox.
1248
     *
1249
     * @return the number of accessible children of this object
1250
     *
1251
     * @see ComponentUI#getAccessibleChildrenCount(JComponent)
1252
     */
1253
    public int getAccessibleChildrenCount()
1254
    {
1255
      ComponentUI ui = getUI();
1256
      int count;
1257
      if (ui != null)
1258
        count = ui.getAccessibleChildrenCount(JComboBox.this);
1259
      else
1260
        count = super.getAccessibleChildrenCount();
1261
      return count;
1262
    }
1263
 
1264
    /**
1265
     * Returns the number of accessible children of this object. The
1266
     * implementation of AccessibleJComboBox delegates this call to the UI
1267
     * of the associated JComboBox.
1268
     *
1269
     * @param index the index of the accessible child to fetch
1270
     *
1271
     * @return the number of accessible children of this object
1272
     *
1273
     * @see ComponentUI#getAccessibleChild(JComponent, int)
1274
     */
1275
    public Accessible getAccessibleChild(int index)
1276
    {
1277
      ComponentUI ui = getUI();
1278
      Accessible child = null;
1279
      if (ui != null)
1280
        child = ui.getAccessibleChild(JComboBox.this, index);
1281
      else
1282
        child = super.getAccessibleChild(index);
1283
      return child;
1284
    }
1285
 
1286
    /**
1287
     * Returns the AccessibleSelection object associated with this object.
1288
     * AccessibleJComboBoxes handle their selection themselves, so this
1289
     * always returns <code>this</code>.
1290
     *
1291
     * @return the AccessibleSelection object associated with this object
1292
     */
1293
    public AccessibleSelection getAccessibleSelection()
1294
    {
1295
      return this;
1296
    }
1297
 
1298
    /**
1299
     * Returns the accessible selection from this AccssibleJComboBox.
1300
     *
1301
     * @param index the index of the selected child to fetch
1302
     *
1303
     * @return the accessible selection from this AccssibleJComboBox
1304
     */
1305
    public Accessible getAccessibleSelection(int index)
1306
    {
1307
      // Get hold of the actual popup.
1308
      Accessible popup = getUI().getAccessibleChild(JComboBox.this, 0);
1309
      Accessible selected = null;
1310
      if (popup != null && popup instanceof ComboPopup)
1311
        {
1312
          ComboPopup cPopup = (ComboPopup) popup;
1313
          // Query the list for the currently selected child.
1314
          JList l = cPopup.getList();
1315
          AccessibleContext listCtx = l.getAccessibleContext();
1316
          if (listCtx != null)
1317
            {
1318
              AccessibleSelection s = listCtx.getAccessibleSelection();
1319
              if (s != null)
1320
                {
1321
                  selected = s.getAccessibleSelection(index);
1322
                }
1323
            }
1324
        }
1325
      return selected;
1326
    }
1327
 
1328
    /**
1329
     * Returns <code>true</code> if the accessible child with the specified
1330
     * <code>index</code> is selected, <code>false</code> otherwise.
1331
     *
1332
     * @param index the index of the accessible child
1333
     *
1334
     * @return <code>true</code> if the accessible child with the specified
1335
     *         <code>index</code> is selected, <code>false</code> otherwise
1336
     */
1337
    public boolean isAccessibleChildSelected(int index)
1338
    {
1339
      return getSelectedIndex() == index;
1340
    }
1341
 
1342
    /**
1343
     * Returns the accessible role for the <code>JComboBox</code> component.
1344
     *
1345
     * @return {@link AccessibleRole#COMBO_BOX}.
1346
     */
1347
    public AccessibleRole getAccessibleRole()
1348
    {
1349
      return AccessibleRole.COMBO_BOX;
1350
    }
1351
 
1352
    /**
1353
     * Returns the accessible action associated to this accessible object.
1354
     * AccessibleJComboBox implements its own AccessibleAction, so this
1355
     * method returns <code>this</code>.
1356
     *
1357
     * @return the accessible action associated to this accessible object
1358
     */
1359
    public AccessibleAction getAccessibleAction()
1360
    {
1361
      return this;
1362
    }
1363
 
1364
    /**
1365
     * Returns the description of the specified action. AccessibleJComboBox
1366
     * implements 1 action (toggle the popup menu) and thus returns
1367
     * <code>UIManager.getString("ComboBox.togglePopupText")</code>
1368
     *
1369
     * @param actionIndex the index of the action for which to return the
1370
     *        description
1371
     *
1372
     * @return the description of the specified action
1373
     */
1374
    public String getAccessibleActionDescription(int actionIndex)
1375
    {
1376
      return UIManager.getString("ComboBox.togglePopupText");
1377
    }
1378
 
1379
    /**
1380
     * Returns the number of accessible actions that can be performed by
1381
     * this object. AccessibleJComboBox implement s one accessible action
1382
     * (toggle the popup menu), so this method always returns <code>1</code>.
1383
     *
1384
     * @return the number of accessible actions that can be performed by
1385
     *         this object
1386
     */
1387
    public int getAccessibleActionCount()
1388
    {
1389
      return 1;
1390
    }
1391
 
1392
    /**
1393
     * Performs the accessible action with the specified index.
1394
     * AccessibleJComboBox has 1 accessible action
1395
     * (<code>actionIndex == 0</code>), which is to toggle the
1396
     * popup menu. All other action indices have no effect and return
1397
     * <code<>false</code>.
1398
     *
1399
     * @param actionIndex the index of the action to perform
1400
     *
1401
     * @return <code>true</code> if the action has been performed,
1402
     *         <code>false</code> otherwise
1403
     */
1404
    public boolean doAccessibleAction(int actionIndex)
1405
    {
1406
      boolean actionPerformed = false;
1407
      if (actionIndex == 0)
1408
        {
1409
          setPopupVisible(! isPopupVisible());
1410
          actionPerformed = true;
1411
        }
1412
      return actionPerformed;
1413
    }
1414
 
1415
    /**
1416
     * Returns the number of selected accessible children of this object. This
1417
     * returns <code>1</code> if the combobox has a selected entry,
1418
     * <code>0</code> otherwise.
1419
     *
1420
     * @return the number of selected accessible children of this object
1421
     */
1422
    public int getAccessibleSelectionCount()
1423
    {
1424
      Object sel = getSelectedItem();
1425
      int count = 0;
1426
      if (sel != null)
1427
        count = 1;
1428
      return count;
1429
    }
1430
 
1431
    /**
1432
     * Sets the current selection to the specified <code>index</code>.
1433
     *
1434
     * @param index the index to set as selection
1435
     */
1436
    public void addAccessibleSelection(int index)
1437
    {
1438
      setSelectedIndex(index);
1439
    }
1440
 
1441
    /**
1442
     * Removes the specified index from the current selection.
1443
     *
1444
     * @param index the index to remove from the selection
1445
     */
1446
    public void removeAccessibleSelection(int index)
1447
    {
1448
      if (getSelectedIndex() == index)
1449
        clearAccessibleSelection();
1450
    }
1451
 
1452
    /**
1453
     * Clears the current selection.
1454
     */
1455
    public void clearAccessibleSelection()
1456
    {
1457
      setSelectedIndex(-1);
1458
    }
1459
 
1460
    /**
1461
     * Multiple selection is not supported by AccessibleJComboBox, so this
1462
     * does nothing.
1463
     */
1464
    public void selectAllAccessibleSelection()
1465
    {
1466
      // Nothing to do here.
1467
    }
1468
  }
1469
 
1470
  private class DefaultKeySelectionManager
1471
      implements KeySelectionManager
1472
  {
1473
 
1474
    public int selectionForKey(char aKey, ComboBoxModel aModel)
1475
    {
1476
      int selectedIndex = getSelectedIndex();
1477
 
1478
      // Start at currently selected item and iterate to end of list
1479
      for (int i = selectedIndex + 1; i < aModel.getSize(); i++)
1480
        {
1481
          String nextItem = aModel.getElementAt(i).toString();
1482
 
1483
          if (nextItem.charAt(0) == aKey)
1484
            return i;
1485
        }
1486
 
1487
      // Wrap to start of list if no match yet
1488
      for (int i = 0; i <= selectedIndex; i++)
1489
        {
1490
          String nextItem = aModel.getElementAt(i).toString();
1491
 
1492
          if (nextItem.charAt(0) == aKey)
1493
            return i;
1494
        }
1495
 
1496
      return - 1;
1497
    }
1498
  }
1499
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.