2 Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
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)
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.
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
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
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. */
41 import java.awt.ItemSelectable;
42 import java.awt.event.ActionEvent;
43 import java.awt.event.ActionListener;
44 import java.awt.event.ItemEvent;
45 import java.awt.event.ItemListener;
46 import java.awt.event.KeyEvent;
47 import java.beans.PropertyChangeEvent;
48 import java.beans.PropertyChangeListener;
49 import java.util.Vector;
51 import javax.accessibility.Accessible;
52 import javax.accessibility.AccessibleAction;
53 import javax.accessibility.AccessibleContext;
54 import javax.accessibility.AccessibleRole;
55 import javax.accessibility.AccessibleSelection;
56 import javax.swing.event.ListDataEvent;
57 import javax.swing.event.ListDataListener;
58 import javax.swing.event.PopupMenuEvent;
59 import javax.swing.event.PopupMenuListener;
60 import javax.swing.plaf.ComboBoxUI;
61 import javax.swing.plaf.ComponentUI;
62 import javax.swing.plaf.basic.ComboPopup;
65 * A component that allows a user to select any item in its list and
66 * displays the selected item to the user. JComboBox also can show/hide a
67 * popup menu containing its list of item whenever the mouse is pressed
70 * @author Andrew Selkirk
71 * @author Olga Rodimina
72 * @author Robert Schuster
74 public class JComboBox extends JComponent implements ItemSelectable,
80 private static final long serialVersionUID = 5654585963292734470L;
83 * Classes implementing this interface are
84 * responsible for matching key characters typed by the user with combo
87 public static interface KeySelectionManager
89 int selectionForKey(char aKey, ComboBoxModel aModel);
93 * Maximum number of rows that should be visible by default in the
96 private static final int DEFAULT_MAXIMUM_ROW_COUNT = 8;
99 * Data model used by JComboBox to keep track of its list data and currently
100 * selected element in the list.
102 protected ComboBoxModel dataModel;
105 * Renderer renders(paints) every object in the combo box list in its
106 * associated list cell. This ListCellRenderer is used only when this
107 * JComboBox is uneditable.
109 protected ListCellRenderer renderer;
112 * Editor that is responsible for editing an object in a combo box list.
114 protected ComboBoxEditor editor;
117 * Number of rows that will be visible in the JComboBox's popup.
119 protected int maximumRowCount;
122 * This field indicates if textfield of this JComboBox is editable or not.
124 protected boolean isEditable;
127 * This field is reference to the current selection of the combo box.
129 protected Object selectedItemReminder;
132 * keySelectionManager
134 protected KeySelectionManager keySelectionManager;
137 * This actionCommand is used in ActionEvent that is fired to JComboBox's
140 protected String actionCommand;
143 * This property indicates if heavyweight popup or lightweight popup will be
144 * used to diplay JComboBox's elements.
146 protected boolean lightWeightPopupEnabled;
149 * The action taken when new item is selected in the JComboBox
151 private Action action;
154 * since 1.4 If this field is set then comboBox's display area for the
155 * selected item will be set by default to this value.
157 private Object prototypeDisplayValue;
160 * Constructs JComboBox object with specified data model for it.
161 * <p>Note that the JComboBox will not change the value that
162 * is preselected by your ComboBoxModel implementation.</p>
164 * @param model Data model that will be used by this JComboBox to keep track
165 * of its list of items.
167 public JComboBox(ComboBoxModel model)
171 setMaximumRowCount(DEFAULT_MAXIMUM_ROW_COUNT);
173 setActionCommand("comboBoxChanged");
175 lightWeightPopupEnabled = true;
182 * Constructs JComboBox with specified list of items.
184 * @param itemArray array containing list of items for this JComboBox
186 public JComboBox(Object[] itemArray)
188 this(new DefaultComboBoxModel(itemArray));
190 if (itemArray.length > 0)
195 * Constructs JComboBox object with specified list of items.
197 * @param itemVector vector containing list of items for this JComboBox.
199 public JComboBox(Vector<?> itemVector)
201 this(new DefaultComboBoxModel(itemVector));
203 if (itemVector.size() > 0)
208 * Constructor. Creates new empty JComboBox. ComboBox's data model is set to
209 * DefaultComboBoxModel.
213 this(new DefaultComboBoxModel());
217 * This method returns true JComboBox is editable and false otherwise
219 * @return boolean true if JComboBox is editable and false otherwise
221 public boolean isEditable()
227 * This method adds ancestor listener to this JComboBox.
229 protected void installAncestorListener()
231 /* FIXME: Need to implement.
233 * Need to add ancestor listener to this JComboBox. This listener
234 * should close combo box's popup list of items whenever it
235 * receives an AncestorEvent.
240 * Set the "UI" property of the combo box, which is a look and feel class
241 * responsible for handling comboBox's input events and painting it.
243 * @param ui The new "UI" property
245 public void setUI(ComboBoxUI ui)
251 * This method sets this comboBox's UI to the UIManager's default for the
252 * current look and feel.
254 public void updateUI()
256 setUI((ComboBoxUI) UIManager.getUI(this));
260 * This method returns the String identifier for the UI class to the used
261 * with the JComboBox.
263 * @return The String identifier for the UI class.
265 public String getUIClassID()
271 * This method returns the UI used to display the JComboBox.
273 * @return The UI used to display the JComboBox.
275 public ComboBoxUI getUI()
277 return (ComboBoxUI) ui;
281 * Set the data model for this JComboBox. This un-registers all listeners
282 * associated with the current model, and re-registers them with the new
285 * @param newDataModel The new data model for this JComboBox
287 public void setModel(ComboBoxModel newDataModel)
289 // dataModel is null if it this method is called from inside the constructors.
290 if (dataModel != null)
292 // Prevents unneccessary updates.
293 if (dataModel == newDataModel)
296 // Removes itself (as DataListener) from the to-be-replaced model.
297 dataModel.removeListDataListener(this);
300 /* Adds itself as a DataListener to the new model.
301 * It is intentioned that this operation will fail with a NullPointerException if the
302 * caller delivered a null argument.
304 newDataModel.addListDataListener(this);
306 // Stores old data model for event notification.
307 ComboBoxModel oldDataModel = dataModel;
308 dataModel = newDataModel;
309 selectedItemReminder = newDataModel.getSelectedItem();
311 // Notifies the listeners of the model change.
312 firePropertyChange("model", oldDataModel, dataModel);
316 * This method returns data model for this comboBox.
318 * @return ComboBoxModel containing items for this combo box.
320 public ComboBoxModel getModel()
326 * This method sets JComboBox's popup to be either lightweight or
327 * heavyweight. If 'enabled' is true then lightweight popup is used and
328 * heavyweight otherwise. By default lightweight popup is used to display
329 * this JComboBox's elements.
331 * @param enabled indicates if lightweight popup or heavyweight popup should
332 * be used to display JComboBox's elements.
334 public void setLightWeightPopupEnabled(boolean enabled)
336 lightWeightPopupEnabled = enabled;
340 * This method returns whether popup menu that is used to display list of
341 * combo box's item is lightWeight or not.
343 * @return boolean true if popup menu is lightweight and false otherwise.
345 public boolean isLightWeightPopupEnabled()
347 return lightWeightPopupEnabled;
351 * This method sets editability of the combo box. If combo box is editable
352 * the user can choose component from the combo box list by typing
353 * component's name in the editor(JTextfield by default). Otherwise if not
354 * editable, the user should use the list to choose the component. This
355 * method fires PropertyChangeEvents to JComboBox's registered
356 * PropertyChangeListeners to indicate that 'editable' property of the
357 * JComboBox has changed.
359 * @param editable indicates if the JComboBox's textfield should be editable
362 public void setEditable(boolean editable)
364 if (isEditable != editable)
366 isEditable = editable;
367 firePropertyChange("editable", !isEditable, isEditable);
372 * Sets number of rows that should be visible in this JComboBox's popup. If
373 * this JComboBox's popup has more elements that maximum number or rows
374 * then popup will have a scroll pane to allow users to view other
377 * @param rowCount number of rows that will be visible in JComboBox's popup.
379 public void setMaximumRowCount(int rowCount)
381 if (maximumRowCount != rowCount)
383 int oldMaximumRowCount = maximumRowCount;
384 maximumRowCount = rowCount;
385 firePropertyChange("maximumRowCount", oldMaximumRowCount,
391 * This method returns number of rows visible in the JComboBox's list of
394 * @return int maximun number of visible rows in the JComboBox's list.
396 public int getMaximumRowCount()
398 return maximumRowCount;
402 * This method sets cell renderer for this JComboBox that will be used to
403 * paint combo box's items. The Renderer should only be used only when
404 * JComboBox is not editable. In the case when JComboBox is editable the
405 * editor must be used. This method also fires PropertyChangeEvent when
406 * cellRendered for this JComboBox has changed.
408 * @param aRenderer cell renderer that will be used by this JComboBox to
409 * paint its elements.
411 public void setRenderer(ListCellRenderer aRenderer)
413 if (renderer != aRenderer)
415 ListCellRenderer oldRenderer = renderer;
416 renderer = aRenderer;
417 firePropertyChange("renderer", oldRenderer, renderer);
422 * This method returns renderer responsible for rendering selected item in
425 * @return ListCellRenderer
427 public ListCellRenderer getRenderer()
433 * Sets editor for this JComboBox
435 * @param newEditor ComboBoxEditor for this JComboBox. This method fires
436 * PropertyChangeEvent when 'editor' property is changed.
438 public void setEditor(ComboBoxEditor newEditor)
440 if (editor == newEditor)
444 editor.removeActionListener(this);
446 ComboBoxEditor oldEditor = editor;
450 editor.addActionListener(this);
452 firePropertyChange("editor", oldEditor, editor);
456 * Returns editor component that is responsible for displaying/editing
457 * selected item in the combo box.
459 * @return ComboBoxEditor
461 public ComboBoxEditor getEditor()
467 * Forces combo box to select given item
469 * @param item element in the combo box to select.
471 public void setSelectedItem(Object item)
473 dataModel.setSelectedItem(item);
478 * Returns currently selected item in the combo box.
479 * The result may be <code>null</code> to indicate that nothing is
480 * currently selected.
482 * @return element that is currently selected in this combo box.
484 public Object getSelectedItem()
486 return dataModel.getSelectedItem();
490 * Forces JComboBox to select component located in the given index in the
492 * <p>If the index is below -1 or exceeds the upper bound an
493 * <code>IllegalArgumentException</code> is thrown.<p/>
494 * <p>If the index is -1 then no item gets selected.</p>
496 * @param index index specifying location of the component that should be
499 public void setSelectedIndex(int index)
501 if (index < -1 || index >= dataModel.getSize())
502 // Fails because index is out of bounds.
503 throw new IllegalArgumentException("illegal index: " + index);
505 // Selects the item at the given index or clears the selection if the
506 // index value is -1.
507 setSelectedItem((index == -1) ? null : dataModel.getElementAt(index));
511 * Returns index of the item that is currently selected in the combo box. If
512 * no item is currently selected, then -1 is returned.
514 * Note: For performance reasons you should minimize invocation of this
515 * method. If the data model is not an instance of
516 * <code>DefaultComboBoxModel</code> the complexity is O(n) where n is the
517 * number of elements in the combo box.
520 * @return int Index specifying location of the currently selected item in the
521 * combo box or -1 if nothing is selected in the combo box.
523 public int getSelectedIndex()
525 Object selectedItem = getSelectedItem();
527 if (selectedItem != null)
529 if (dataModel instanceof DefaultComboBoxModel)
530 // Uses special method of DefaultComboBoxModel to retrieve the index.
531 return ((DefaultComboBoxModel) dataModel).getIndexOf(selectedItem);
534 // Iterates over all items to retrieve the index.
535 int size = dataModel.getSize();
537 for (int i = 0; i < size; i++)
539 Object o = dataModel.getElementAt(i);
541 // XXX: Is special handling of ComparableS neccessary?
542 if ((selectedItem != null) ? selectedItem.equals(o) : o == null)
548 // returns that no item is currently selected
553 * Returns an object that is used as the display value when calculating the
554 * preferred size for the combo box. This value is, of course, never
555 * displayed anywhere.
557 * @return The prototype display value (possibly <code>null</code>).
560 * @see #setPrototypeDisplayValue(Object)
562 public Object getPrototypeDisplayValue()
564 return prototypeDisplayValue;
568 * Sets the object that is assumed to be the displayed item when calculating
569 * the preferred size for the combo box. A {@link PropertyChangeEvent} (with
570 * the name <code>prototypeDisplayValue</code>) is sent to all registered
573 * @param value the new value (<code>null</code> permitted).
576 * @see #getPrototypeDisplayValue()
578 public void setPrototypeDisplayValue(Object value)
580 Object oldValue = prototypeDisplayValue;
581 prototypeDisplayValue = value;
582 firePropertyChange("prototypeDisplayValue", oldValue, value);
586 * This method adds given element to this JComboBox.
587 * <p>A <code>RuntimeException</code> is thrown if the data model is not
588 * an instance of {@link MutableComboBoxModel}.</p>
590 * @param element element to add
592 public void addItem(Object element)
594 if (dataModel instanceof MutableComboBoxModel)
595 ((MutableComboBoxModel) dataModel).addElement(element);
597 throw new RuntimeException("Unable to add the item because the data "
598 + "model it is not an instance of "
599 + "MutableComboBoxModel.");
603 * Inserts given element at the specified index to this JComboBox.
604 * <p>A <code>RuntimeException</code> is thrown if the data model is not
605 * an instance of {@link MutableComboBoxModel}.</p>
607 * @param element element to insert
608 * @param index position where to insert the element
610 public void insertItemAt(Object element, int index)
612 if (dataModel instanceof MutableComboBoxModel)
613 ((MutableComboBoxModel) dataModel).insertElementAt(element, index);
615 throw new RuntimeException("Unable to insert the item because the data "
616 + "model it is not an instance of "
617 + "MutableComboBoxModel.");
621 * This method removes given element from this JComboBox.
622 * <p>A <code>RuntimeException</code> is thrown if the data model is not
623 * an instance of {@link MutableComboBoxModel}.</p>
625 * @param element element to remove
627 public void removeItem(Object element)
629 if (dataModel instanceof MutableComboBoxModel)
630 ((MutableComboBoxModel) dataModel).removeElement(element);
632 throw new RuntimeException("Unable to remove the item because the data "
633 + "model it is not an instance of "
634 + "MutableComboBoxModel.");
638 * This method remove element location in the specified index in the
640 * <p>A <code>RuntimeException</code> is thrown if the data model is not
641 * an instance of {@link MutableComboBoxModel}.</p>
643 * @param index index specifying position of the element to remove
645 public void removeItemAt(int index)
647 if (dataModel instanceof MutableComboBoxModel)
648 ((MutableComboBoxModel) dataModel).removeElementAt(index);
650 throw new RuntimeException("Unable to remove the item because the data "
651 + "model it is not an instance of "
652 + "MutableComboBoxModel.");
656 * This method removes all elements from this JComboBox.
658 * A <code>RuntimeException</code> is thrown if the data model is not an
659 * instance of {@link MutableComboBoxModel}.
662 public void removeAllItems()
664 if (dataModel instanceof DefaultComboBoxModel)
665 // Uses special method if we have a DefaultComboBoxModel.
666 ((DefaultComboBoxModel) dataModel).removeAllElements();
667 else if (dataModel instanceof MutableComboBoxModel)
669 // Iterates over all items and removes each.
670 MutableComboBoxModel mcbm = (MutableComboBoxModel) dataModel;
672 // We intentionally remove the items backwards to support models which
673 // shift their content to the beginning (e.g. linked lists)
674 for (int i = mcbm.getSize() - 1; i >= 0; i--)
675 mcbm.removeElementAt(i);
678 throw new RuntimeException("Unable to remove the items because the data "
679 + "model it is not an instance of "
680 + "MutableComboBoxModel.");
684 * This method displays popup with list of combo box's items on the screen
686 public void showPopup()
688 setPopupVisible(true);
692 * This method hides popup containing list of combo box's items
694 public void hidePopup()
696 setPopupVisible(false);
700 * This method either displayes or hides the popup containing list of combo
703 * @param visible show popup if 'visible' is true and hide it otherwise
705 public void setPopupVisible(boolean visible)
707 getUI().setPopupVisible(this, visible);
711 * Checks if popup is currently visible on the screen.
713 * @return boolean true if popup is visible and false otherwise
715 public boolean isPopupVisible()
717 return getUI().isPopupVisible(this);
721 * This method sets actionCommand to the specified string. ActionEvent fired
722 * to this JComboBox registered ActionListeners will contain this
725 * @param aCommand new action command for the JComboBox's ActionEvent
727 public void setActionCommand(String aCommand)
729 actionCommand = aCommand;
733 * Returns actionCommand associated with the ActionEvent fired by the
734 * JComboBox to its registered ActionListeners.
736 * @return String actionCommand for the ActionEvent
738 public String getActionCommand()
740 return actionCommand;
746 * @param a action to set
748 public void setAction(Action a)
752 configurePropertiesFromAction(action);
754 // FIXME: remove from old action and add to new action
755 // PropertyChangeListener to listen to changes in the action
756 addActionListener(action);
760 * This method returns Action that is invoked when selected item is changed
765 public Action getAction()
771 * Configure properties of the JComboBox by reading properties of specified
772 * action. This method always sets the comboBox's "enabled" property to the
773 * value of the Action's "enabled" property.
775 * @param a An Action to configure the combo box from
777 protected void configurePropertiesFromAction(Action a)
782 setToolTipText(null);
786 setEnabled(a.isEnabled());
787 setToolTipText((String) (a.getValue(Action.SHORT_DESCRIPTION)));
792 * Creates PropertyChangeListener to listen for the changes in comboBox's
795 * @param action action to listen to for property changes
797 * @return a PropertyChangeListener that listens to changes in
800 protected PropertyChangeListener createActionPropertyChangeListener(Action action)
802 return new PropertyChangeListener()
804 public void propertyChange(PropertyChangeEvent e)
806 Action act = (Action) (e.getSource());
807 configurePropertiesFromAction(act);
813 * This method fires ItemEvent to this JComboBox's registered ItemListeners.
814 * This method is invoked when currently selected item in this combo box
817 * @param e the ItemEvent describing the change in the combo box's
820 protected void fireItemStateChanged(ItemEvent e)
822 ItemListener[] ll = getItemListeners();
824 for (int i = 0; i < ll.length; i++)
825 ll[i].itemStateChanged(e);
829 * This method fires ActionEvent to this JComboBox's registered
830 * ActionListeners. This method is invoked when user explicitly changes
831 * currently selected item.
833 protected void fireActionEvent()
835 ActionListener[] ll = getActionListeners();
837 for (int i = 0; i < ll.length; i++)
838 ll[i].actionPerformed(new ActionEvent(this,
839 ActionEvent.ACTION_PERFORMED,
844 * Fires a popupMenuCanceled() event to all <code>PopupMenuListeners</code>.
846 * Note: This method is intended for use by plaf classes only.
848 public void firePopupMenuCanceled()
850 PopupMenuListener[] listeners = getPopupMenuListeners();
851 PopupMenuEvent e = new PopupMenuEvent(this);
852 for (int i = 0; i < listeners.length; i++)
853 listeners[i].popupMenuCanceled(e);
857 * Fires a popupMenuWillBecomeInvisible() event to all
858 * <code>PopupMenuListeners</code>.
860 * Note: This method is intended for use by plaf classes only.
862 public void firePopupMenuWillBecomeInvisible()
864 PopupMenuListener[] listeners = getPopupMenuListeners();
865 PopupMenuEvent e = new PopupMenuEvent(this);
866 for (int i = 0; i < listeners.length; i++)
867 listeners[i].popupMenuWillBecomeInvisible(e);
871 * Fires a popupMenuWillBecomeVisible() event to all
872 * <code>PopupMenuListeners</code>.
874 * Note: This method is intended for use by plaf classes only.
876 public void firePopupMenuWillBecomeVisible()
878 PopupMenuListener[] listeners = getPopupMenuListeners();
879 PopupMenuEvent e = new PopupMenuEvent(this);
880 for (int i = 0; i < listeners.length; i++)
881 listeners[i].popupMenuWillBecomeVisible(e);
885 * This method is invoked whenever selected item changes in the combo box's
886 * data model. It fires ItemEvent and ActionEvent to all registered
887 * ComboBox's ItemListeners and ActionListeners respectively, indicating
890 protected void selectedItemChanged()
892 // Fire ItemEvent to indicated that previously selected item is now
894 if (selectedItemReminder != null)
895 fireItemStateChanged(new ItemEvent(this, ItemEvent.ITEM_STATE_CHANGED,
896 selectedItemReminder,
897 ItemEvent.DESELECTED));
899 // Fire ItemEvent to indicate that new item is selected
900 Object newSelection = getSelectedItem();
901 if (newSelection != null)
902 fireItemStateChanged(new ItemEvent(this, ItemEvent.ITEM_STATE_CHANGED,
903 newSelection, ItemEvent.SELECTED));
905 // Fire Action Event to JComboBox's registered listeners
908 selectedItemReminder = newSelection;
912 * Returns Object array of size 1 containing currently selected element in
915 * @return Object[] Object array of size 1 containing currently selected
916 * element in the JComboBox.
918 public Object[] getSelectedObjects()
920 return new Object[] { getSelectedItem() };
924 * This method handles actionEvents fired by the ComboBoxEditor. It changes
925 * this JComboBox's selection to the new value currently in the editor and
926 * hides list of combo box items.
928 * @param e the ActionEvent
930 public void actionPerformed(ActionEvent e)
932 setSelectedItem(getEditor().getItem());
933 setPopupVisible(false);
937 * This method selects item in this combo box that matches specified
938 * specified keyChar and returns true if such item is found. Otherwise
941 * @param keyChar character indicating which item in the combo box should be
944 * @return boolean true if item corresponding to the specified keyChar
945 * exists in the combo box. Otherwise false is returned.
947 public boolean selectWithKeyChar(char keyChar)
949 if (keySelectionManager == null)
951 keySelectionManager = createDefaultKeySelectionManager();
954 int index = keySelectionManager.selectionForKey(keyChar, getModel());
955 boolean retVal = false;
958 setSelectedIndex(index);
965 * The part of implementation of ListDataListener interface. This method is
966 * invoked when some items where added to the JComboBox's data model.
968 * @param event ListDataEvent describing the change
970 public void intervalAdded(ListDataEvent event)
972 // FIXME: Need to implement
977 * The part of implementation of ListDataListener interface. This method is
978 * invoked when some items where removed from the JComboBox's data model.
980 * @param event ListDataEvent describing the change.
982 public void intervalRemoved(ListDataEvent event)
984 // FIXME: Need to implement
989 * The part of implementation of ListDataListener interface. This method is
990 * invoked when contents of the JComboBox's data model changed.
992 * @param event ListDataEvent describing the change
994 public void contentsChanged(ListDataEvent event)
996 // if first and last index of the given ListDataEvent are both -1,
997 // then it indicates that selected item in the combo box data model
999 if (event.getIndex0() == -1 && event.getIndex1() == -1)
1000 selectedItemChanged();
1004 * This method disables or enables JComboBox. If the JComboBox is enabled,
1005 * then user is able to make item choice, otherwise if JComboBox is
1006 * disabled then user is not able to make a selection.
1008 * @param enabled if 'enabled' is true then enable JComboBox and disable it
1010 public void setEnabled(boolean enabled)
1012 boolean oldEnabled = super.isEnabled();
1013 if (enabled != oldEnabled)
1015 super.setEnabled(enabled);
1016 firePropertyChange("enabled", oldEnabled, enabled);
1021 * This method initializes specified ComboBoxEditor to display given item.
1023 * @param anEditor ComboBoxEditor to initialize
1024 * @param anItem Item that should displayed in the specified editor
1026 public void configureEditor(ComboBoxEditor anEditor, Object anItem)
1028 anEditor.setItem(anItem);
1032 * This method is fired whenever a key is pressed with the combo box
1035 * @param e The KeyEvent indicating which key was pressed.
1037 public void processKeyEvent(KeyEvent e)
1039 if (e.getKeyCode() == KeyEvent.VK_TAB)
1040 setPopupVisible(false);
1042 super.processKeyEvent(e);
1046 * setKeySelectionManager
1050 public void setKeySelectionManager(KeySelectionManager aManager)
1052 keySelectionManager = aManager;
1056 * getKeySelectionManager
1058 * @return JComboBox.KeySelectionManager
1060 public KeySelectionManager getKeySelectionManager()
1062 return keySelectionManager;
1066 * This method returns number of elements in this JComboBox
1068 * @return int number of elements in this JComboBox
1070 public int getItemCount()
1072 return dataModel.getSize();
1076 * Returns elements located in the combo box at the given index.
1078 * @param index index specifying location of the component to return.
1080 * @return component in the combo box that is located in the given index.
1082 public Object getItemAt(int index)
1084 return dataModel.getElementAt(index);
1088 * createDefaultKeySelectionManager
1090 * @return KeySelectionManager
1092 protected KeySelectionManager createDefaultKeySelectionManager()
1094 return new DefaultKeySelectionManager();
1098 * Returns an implementation-dependent string describing the attributes of
1099 * this <code>JComboBox</code>.
1101 * @return A string describing the attributes of this <code>JComboBox</code>
1102 * (never <code>null</code>).
1104 protected String paramString()
1106 String superParamStr = super.paramString();
1107 StringBuffer sb = new StringBuffer();
1108 sb.append(",isEditable=").append(isEditable());
1109 sb.append(",lightWeightPopupEnabled=").append(isLightWeightPopupEnabled());
1110 sb.append(",maximumRowCount=").append(getMaximumRowCount());
1112 sb.append(",selectedItemReminder=");
1113 if (selectedItemReminder != null)
1114 sb.append(selectedItemReminder);
1115 return superParamStr + sb.toString();
1119 * Returns the object that provides accessibility features for this
1120 * <code>JComboBox</code> component.
1122 * @return The accessible context (an instance of
1123 * {@link AccessibleJComboBox}).
1125 public AccessibleContext getAccessibleContext()
1127 if (accessibleContext == null)
1128 accessibleContext = new AccessibleJComboBox();
1130 return accessibleContext;
1134 * This methods adds specified ActionListener to this JComboBox.
1136 * @param listener to add
1138 public void addActionListener(ActionListener listener)
1140 listenerList.add(ActionListener.class, listener);
1144 * This method removes specified ActionListener from this JComboBox.
1146 * @param listener ActionListener
1148 public void removeActionListener(ActionListener listener)
1150 listenerList.remove(ActionListener.class, listener);
1154 * This method returns array of ActionListeners that are registered with
1159 public ActionListener[] getActionListeners()
1161 return (ActionListener[]) getListeners(ActionListener.class);
1165 * This method registers given ItemListener with this JComboBox
1167 * @param listener to remove
1169 public void addItemListener(ItemListener listener)
1171 listenerList.add(ItemListener.class, listener);
1175 * This method unregisters given ItemListener from this JComboBox
1177 * @param listener to remove
1179 public void removeItemListener(ItemListener listener)
1181 listenerList.remove(ItemListener.class, listener);
1185 * This method returns array of ItemListeners that are registered with this
1190 public ItemListener[] getItemListeners()
1192 return (ItemListener[]) getListeners(ItemListener.class);
1196 * Adds PopupMenuListener to combo box to listen to the events fired by the
1197 * combo box's popup menu containing its list of items
1199 * @param listener to add
1201 public void addPopupMenuListener(PopupMenuListener listener)
1203 listenerList.add(PopupMenuListener.class, listener);
1207 * Removes PopupMenuListener to combo box to listen to the events fired by
1208 * the combo box's popup menu containing its list of items
1210 * @param listener to add
1212 public void removePopupMenuListener(PopupMenuListener listener)
1214 listenerList.remove(PopupMenuListener.class, listener);
1218 * Returns array of PopupMenuListeners that are registered with combo box.
1220 public PopupMenuListener[] getPopupMenuListeners()
1222 return (PopupMenuListener[]) getListeners(PopupMenuListener.class);
1226 * Accessibility support for <code>JComboBox</code>.
1228 protected class AccessibleJComboBox extends AccessibleJComponent
1229 implements AccessibleAction, AccessibleSelection
1231 private static final long serialVersionUID = 8217828307256675666L;
1234 * @specnote This constructor was protected in 1.4, but made public
1237 public AccessibleJComboBox()
1239 // Nothing to do here.
1243 * Returns the number of accessible children of this object. The
1244 * implementation of AccessibleJComboBox delegates this call to the UI
1245 * of the associated JComboBox.
1247 * @return the number of accessible children of this object
1249 * @see ComponentUI#getAccessibleChildrenCount(JComponent)
1251 public int getAccessibleChildrenCount()
1253 ComponentUI ui = getUI();
1256 count = ui.getAccessibleChildrenCount(JComboBox.this);
1258 count = super.getAccessibleChildrenCount();
1263 * Returns the number of accessible children of this object. The
1264 * implementation of AccessibleJComboBox delegates this call to the UI
1265 * of the associated JComboBox.
1267 * @param index the index of the accessible child to fetch
1269 * @return the number of accessible children of this object
1271 * @see ComponentUI#getAccessibleChild(JComponent, int)
1273 public Accessible getAccessibleChild(int index)
1275 ComponentUI ui = getUI();
1276 Accessible child = null;
1278 child = ui.getAccessibleChild(JComboBox.this, index);
1280 child = super.getAccessibleChild(index);
1285 * Returns the AccessibleSelection object associated with this object.
1286 * AccessibleJComboBoxes handle their selection themselves, so this
1287 * always returns <code>this</code>.
1289 * @return the AccessibleSelection object associated with this object
1291 public AccessibleSelection getAccessibleSelection()
1297 * Returns the accessible selection from this AccssibleJComboBox.
1299 * @param index the index of the selected child to fetch
1301 * @return the accessible selection from this AccssibleJComboBox
1303 public Accessible getAccessibleSelection(int index)
1305 // Get hold of the actual popup.
1306 Accessible popup = getUI().getAccessibleChild(JComboBox.this, 0);
1307 Accessible selected = null;
1308 if (popup != null && popup instanceof ComboPopup)
1310 ComboPopup cPopup = (ComboPopup) popup;
1311 // Query the list for the currently selected child.
1312 JList l = cPopup.getList();
1313 AccessibleContext listCtx = l.getAccessibleContext();
1314 if (listCtx != null)
1316 AccessibleSelection s = listCtx.getAccessibleSelection();
1319 selected = s.getAccessibleSelection(index);
1327 * Returns <code>true</code> if the accessible child with the specified
1328 * <code>index</code> is selected, <code>false</code> otherwise.
1330 * @param index the index of the accessible child
1332 * @return <code>true</code> if the accessible child with the specified
1333 * <code>index</code> is selected, <code>false</code> otherwise
1335 public boolean isAccessibleChildSelected(int index)
1337 return getSelectedIndex() == index;
1341 * Returns the accessible role for the <code>JComboBox</code> component.
1343 * @return {@link AccessibleRole#COMBO_BOX}.
1345 public AccessibleRole getAccessibleRole()
1347 return AccessibleRole.COMBO_BOX;
1351 * Returns the accessible action associated to this accessible object.
1352 * AccessibleJComboBox implements its own AccessibleAction, so this
1353 * method returns <code>this</code>.
1355 * @return the accessible action associated to this accessible object
1357 public AccessibleAction getAccessibleAction()
1363 * Returns the description of the specified action. AccessibleJComboBox
1364 * implements 1 action (toggle the popup menu) and thus returns
1365 * <code>UIManager.getString("ComboBox.togglePopupText")</code>
1367 * @param actionIndex the index of the action for which to return the
1370 * @return the description of the specified action
1372 public String getAccessibleActionDescription(int actionIndex)
1374 return UIManager.getString("ComboBox.togglePopupText");
1378 * Returns the number of accessible actions that can be performed by
1379 * this object. AccessibleJComboBox implement s one accessible action
1380 * (toggle the popup menu), so this method always returns <code>1</code>.
1382 * @return the number of accessible actions that can be performed by
1385 public int getAccessibleActionCount()
1391 * Performs the accessible action with the specified index.
1392 * AccessibleJComboBox has 1 accessible action
1393 * (<code>actionIndex == 0</code>), which is to toggle the
1394 * popup menu. All other action indices have no effect and return
1395 * <code<>false</code>.
1397 * @param actionIndex the index of the action to perform
1399 * @return <code>true</code> if the action has been performed,
1400 * <code>false</code> otherwise
1402 public boolean doAccessibleAction(int actionIndex)
1404 boolean actionPerformed = false;
1405 if (actionIndex == 0)
1407 setPopupVisible(! isPopupVisible());
1408 actionPerformed = true;
1410 return actionPerformed;
1414 * Returns the number of selected accessible children of this object. This
1415 * returns <code>1</code> if the combobox has a selected entry,
1416 * <code>0</code> otherwise.
1418 * @return the number of selected accessible children of this object
1420 public int getAccessibleSelectionCount()
1422 Object sel = getSelectedItem();
1430 * Sets the current selection to the specified <code>index</code>.
1432 * @param index the index to set as selection
1434 public void addAccessibleSelection(int index)
1436 setSelectedIndex(index);
1440 * Removes the specified index from the current selection.
1442 * @param index the index to remove from the selection
1444 public void removeAccessibleSelection(int index)
1446 if (getSelectedIndex() == index)
1447 clearAccessibleSelection();
1451 * Clears the current selection.
1453 public void clearAccessibleSelection()
1455 setSelectedIndex(-1);
1459 * Multiple selection is not supported by AccessibleJComboBox, so this
1462 public void selectAllAccessibleSelection()
1464 // Nothing to do here.
1468 private class DefaultKeySelectionManager
1469 implements KeySelectionManager
1472 public int selectionForKey(char aKey, ComboBoxModel aModel)
1474 int selectedIndex = getSelectedIndex();
1476 // Start at currently selected item and iterate to end of list
1477 for (int i = selectedIndex + 1; i < aModel.getSize(); i++)
1479 String nextItem = aModel.getElementAt(i).toString();
1481 if (nextItem.charAt(0) == aKey)
1485 // Wrap to start of list if no match yet
1486 for (int i = 0; i <= selectedIndex; i++)
1488 String nextItem = aModel.getElementAt(i).toString();
1490 if (nextItem.charAt(0) == aKey)