| GNU Classpath (0.95) | |
| Frames | No Frames |
1: /* 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 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; 50: 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; 63: 64: /** 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 68: * over it. 69: * 70: * @author Andrew Selkirk 71: * @author Olga Rodimina 72: * @author Robert Schuster 73: */ 74: public class JComboBox extends JComponent implements ItemSelectable, 75: ListDataListener, 76: ActionListener, 77: Accessible 78: { 79: 80: private static final long serialVersionUID = 5654585963292734470L; 81: 82: /** 83: * Classes implementing this interface are 84: * responsible for matching key characters typed by the user with combo 85: * box's items. 86: */ 87: public static interface KeySelectionManager 88: { 89: int selectionForKey(char aKey, ComboBoxModel aModel); 90: } 91: 92: /** 93: * Maximum number of rows that should be visible by default in the 94: * JComboBox's popup 95: */ 96: private static final int DEFAULT_MAXIMUM_ROW_COUNT = 8; 97: 98: /** 99: * Data model used by JComboBox to keep track of its list data and currently 100: * selected element in the list. 101: */ 102: protected ComboBoxModel dataModel; 103: 104: /** 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. 108: */ 109: protected ListCellRenderer renderer; 110: 111: /** 112: * Editor that is responsible for editing an object in a combo box list. 113: */ 114: protected ComboBoxEditor editor; 115: 116: /** 117: * Number of rows that will be visible in the JComboBox's popup. 118: */ 119: protected int maximumRowCount; 120: 121: /** 122: * This field indicates if textfield of this JComboBox is editable or not. 123: */ 124: protected boolean isEditable; 125: 126: /** 127: * This field is reference to the current selection of the combo box. 128: */ 129: protected Object selectedItemReminder; 130: 131: /** 132: * keySelectionManager 133: */ 134: protected KeySelectionManager keySelectionManager; 135: 136: /** 137: * This actionCommand is used in ActionEvent that is fired to JComboBox's 138: * ActionListeneres. 139: */ 140: protected String actionCommand; 141: 142: /** 143: * This property indicates if heavyweight popup or lightweight popup will be 144: * used to diplay JComboBox's elements. 145: */ 146: protected boolean lightWeightPopupEnabled; 147: 148: /** 149: * The action taken when new item is selected in the JComboBox 150: */ 151: private Action action; 152: 153: /** 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. 156: */ 157: private Object prototypeDisplayValue; 158: 159: /** 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> 163: * 164: * @param model Data model that will be used by this JComboBox to keep track 165: * of its list of items. 166: */ 167: public JComboBox(ComboBoxModel model) 168: { 169: setEditable(false); 170: setEnabled(true); 171: setMaximumRowCount(DEFAULT_MAXIMUM_ROW_COUNT); 172: setModel(model); 173: setActionCommand("comboBoxChanged"); 174: 175: lightWeightPopupEnabled = true; 176: isEditable = false; 177: 178: updateUI(); 179: } 180: 181: /** 182: * Constructs JComboBox with specified list of items. 183: * 184: * @param itemArray array containing list of items for this JComboBox 185: */ 186: public JComboBox(Object[] itemArray) 187: { 188: this(new DefaultComboBoxModel(itemArray)); 189: 190: if (itemArray.length > 0) 191: setSelectedIndex(0); 192: } 193: 194: /** 195: * Constructs JComboBox object with specified list of items. 196: * 197: * @param itemVector vector containing list of items for this JComboBox. 198: */ 199: public JComboBox(Vector<?> itemVector) 200: { 201: this(new DefaultComboBoxModel(itemVector)); 202: 203: if (itemVector.size() > 0) 204: setSelectedIndex(0); 205: } 206: 207: /** 208: * Constructor. Creates new empty JComboBox. ComboBox's data model is set to 209: * DefaultComboBoxModel. 210: */ 211: public JComboBox() 212: { 213: this(new DefaultComboBoxModel()); 214: } 215: 216: /** 217: * This method returns true JComboBox is editable and false otherwise 218: * 219: * @return boolean true if JComboBox is editable and false otherwise 220: */ 221: public boolean isEditable() 222: { 223: return isEditable; 224: } 225: 226: /* 227: * This method adds ancestor listener to this JComboBox. 228: */ 229: protected void installAncestorListener() 230: { 231: /* FIXME: Need to implement. 232: * 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. 236: */ 237: } 238: 239: /** 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. 242: * 243: * @param ui The new "UI" property 244: */ 245: public void setUI(ComboBoxUI ui) 246: { 247: super.setUI(ui); 248: } 249: 250: /** 251: * This method sets this comboBox's UI to the UIManager's default for the 252: * current look and feel. 253: */ 254: public void updateUI() 255: { 256: setUI((ComboBoxUI) UIManager.getUI(this)); 257: } 258: 259: /** 260: * This method returns the String identifier for the UI class to the used 261: * with the JComboBox. 262: * 263: * @return The String identifier for the UI class. 264: */ 265: public String getUIClassID() 266: { 267: return "ComboBoxUI"; 268: } 269: 270: /** 271: * This method returns the UI used to display the JComboBox. 272: * 273: * @return The UI used to display the JComboBox. 274: */ 275: public ComboBoxUI getUI() 276: { 277: return (ComboBoxUI) ui; 278: } 279: 280: /** 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 283: * model. 284: * 285: * @param newDataModel The new data model for this JComboBox 286: */ 287: public void setModel(ComboBoxModel newDataModel) 288: { 289: // dataModel is null if it this method is called from inside the constructors. 290: if (dataModel != null) 291: { 292: // Prevents unneccessary updates. 293: if (dataModel == newDataModel) 294: return; 295: 296: // Removes itself (as DataListener) from the to-be-replaced model. 297: dataModel.removeListDataListener(this); 298: } 299: 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. 303: */ 304: newDataModel.addListDataListener(this); 305: 306: // Stores old data model for event notification. 307: ComboBoxModel oldDataModel = dataModel; 308: dataModel = newDataModel; 309: selectedItemReminder = newDataModel.getSelectedItem(); 310: 311: // Notifies the listeners of the model change. 312: firePropertyChange("model", oldDataModel, dataModel); 313: } 314: 315: /** 316: * This method returns data model for this comboBox. 317: * 318: * @return ComboBoxModel containing items for this combo box. 319: */ 320: public ComboBoxModel getModel() 321: { 322: return dataModel; 323: } 324: 325: /** 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. 330: * 331: * @param enabled indicates if lightweight popup or heavyweight popup should 332: * be used to display JComboBox's elements. 333: */ 334: public void setLightWeightPopupEnabled(boolean enabled) 335: { 336: lightWeightPopupEnabled = enabled; 337: } 338: 339: /** 340: * This method returns whether popup menu that is used to display list of 341: * combo box's item is lightWeight or not. 342: * 343: * @return boolean true if popup menu is lightweight and false otherwise. 344: */ 345: public boolean isLightWeightPopupEnabled() 346: { 347: return lightWeightPopupEnabled; 348: } 349: 350: /** 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. 358: * 359: * @param editable indicates if the JComboBox's textfield should be editable 360: * or not. 361: */ 362: public void setEditable(boolean editable) 363: { 364: if (isEditable != editable) 365: { 366: isEditable = editable; 367: firePropertyChange("editable", !isEditable, isEditable); 368: } 369: } 370: 371: /** 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 375: * elements. 376: * 377: * @param rowCount number of rows that will be visible in JComboBox's popup. 378: */ 379: public void setMaximumRowCount(int rowCount) 380: { 381: if (maximumRowCount != rowCount) 382: { 383: int oldMaximumRowCount = maximumRowCount; 384: maximumRowCount = rowCount; 385: firePropertyChange("maximumRowCount", oldMaximumRowCount, 386: maximumRowCount); 387: } 388: } 389: 390: /** 391: * This method returns number of rows visible in the JComboBox's list of 392: * items. 393: * 394: * @return int maximun number of visible rows in the JComboBox's list. 395: */ 396: public int getMaximumRowCount() 397: { 398: return maximumRowCount; 399: } 400: 401: /** 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. 407: * 408: * @param aRenderer cell renderer that will be used by this JComboBox to 409: * paint its elements. 410: */ 411: public void setRenderer(ListCellRenderer aRenderer) 412: { 413: if (renderer != aRenderer) 414: { 415: ListCellRenderer oldRenderer = renderer; 416: renderer = aRenderer; 417: firePropertyChange("renderer", oldRenderer, renderer); 418: } 419: } 420: 421: /** 422: * This method returns renderer responsible for rendering selected item in 423: * the combo box 424: * 425: * @return ListCellRenderer 426: */ 427: public ListCellRenderer getRenderer() 428: { 429: return renderer; 430: } 431: 432: /** 433: * Sets editor for this JComboBox 434: * 435: * @param newEditor ComboBoxEditor for this JComboBox. This method fires 436: * PropertyChangeEvent when 'editor' property is changed. 437: */ 438: public void setEditor(ComboBoxEditor newEditor) 439: { 440: if (editor == newEditor) 441: return; 442: 443: if (editor != null) 444: editor.removeActionListener(this); 445: 446: ComboBoxEditor oldEditor = editor; 447: editor = newEditor; 448: 449: if (editor != null) 450: editor.addActionListener(this); 451: 452: firePropertyChange("editor", oldEditor, editor); 453: } 454: 455: /** 456: * Returns editor component that is responsible for displaying/editing 457: * selected item in the combo box. 458: * 459: * @return ComboBoxEditor 460: */ 461: public ComboBoxEditor getEditor() 462: { 463: return editor; 464: } 465: 466: /** 467: * Forces combo box to select given item 468: * 469: * @param item element in the combo box to select. 470: */ 471: public void setSelectedItem(Object item) 472: { 473: dataModel.setSelectedItem(item); 474: fireActionEvent(); 475: } 476: 477: /** 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. 481: * 482: * @return element that is currently selected in this combo box. 483: */ 484: public Object getSelectedItem() 485: { 486: return dataModel.getSelectedItem(); 487: } 488: 489: /** 490: * Forces JComboBox to select component located in the given index in the 491: * combo box. 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> 495: * 496: * @param index index specifying location of the component that should be 497: * selected. 498: */ 499: public void setSelectedIndex(int index) 500: { 501: if (index < -1 || index >= dataModel.getSize()) 502: // Fails because index is out of bounds. 503: throw new IllegalArgumentException("illegal index: " + index); 504: else 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)); 508: } 509: 510: /** 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. 513: * <p> 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. 518: * </p> 519: * 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. 522: */ 523: public int getSelectedIndex() 524: { 525: Object selectedItem = getSelectedItem(); 526: 527: if (selectedItem != null) 528: { 529: if (dataModel instanceof DefaultComboBoxModel) 530: // Uses special method of DefaultComboBoxModel to retrieve the index. 531: return ((DefaultComboBoxModel) dataModel).getIndexOf(selectedItem); 532: else 533: { 534: // Iterates over all items to retrieve the index. 535: int size = dataModel.getSize(); 536: 537: for (int i = 0; i < size; i++) 538: { 539: Object o = dataModel.getElementAt(i); 540: 541: // XXX: Is special handling of ComparableS neccessary? 542: if ((selectedItem != null) ? selectedItem.equals(o) : o == null) 543: return i; 544: } 545: } 546: } 547: 548: // returns that no item is currently selected 549: return -1; 550: } 551: 552: /** 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. 556: * 557: * @return The prototype display value (possibly <code>null</code>). 558: * 559: * @since 1.4 560: * @see #setPrototypeDisplayValue(Object) 561: */ 562: public Object getPrototypeDisplayValue() 563: { 564: return prototypeDisplayValue; 565: } 566: 567: /** 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 571: * listeners. 572: * 573: * @param value the new value (<code>null</code> permitted). 574: * 575: * @since 1.4 576: * @see #getPrototypeDisplayValue() 577: */ 578: public void setPrototypeDisplayValue(Object value) 579: { 580: Object oldValue = prototypeDisplayValue; 581: prototypeDisplayValue = value; 582: firePropertyChange("prototypeDisplayValue", oldValue, value); 583: } 584: 585: /** 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> 589: * 590: * @param element element to add 591: */ 592: public void addItem(Object element) 593: { 594: if (dataModel instanceof MutableComboBoxModel) 595: ((MutableComboBoxModel) dataModel).addElement(element); 596: else 597: throw new RuntimeException("Unable to add the item because the data " 598: + "model it is not an instance of " 599: + "MutableComboBoxModel."); 600: } 601: 602: /** 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> 606: * 607: * @param element element to insert 608: * @param index position where to insert the element 609: */ 610: public void insertItemAt(Object element, int index) 611: { 612: if (dataModel instanceof MutableComboBoxModel) 613: ((MutableComboBoxModel) dataModel).insertElementAt(element, index); 614: else 615: throw new RuntimeException("Unable to insert the item because the data " 616: + "model it is not an instance of " 617: + "MutableComboBoxModel."); 618: } 619: 620: /** 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> 624: * 625: * @param element element to remove 626: */ 627: public void removeItem(Object element) 628: { 629: if (dataModel instanceof MutableComboBoxModel) 630: ((MutableComboBoxModel) dataModel).removeElement(element); 631: else 632: throw new RuntimeException("Unable to remove the item because the data " 633: + "model it is not an instance of " 634: + "MutableComboBoxModel."); 635: } 636: 637: /** 638: * This method remove element location in the specified index in the 639: * JComboBox. 640: * <p>A <code>RuntimeException</code> is thrown if the data model is not 641: * an instance of {@link MutableComboBoxModel}.</p> 642: * 643: * @param index index specifying position of the element to remove 644: */ 645: public void removeItemAt(int index) 646: { 647: if (dataModel instanceof MutableComboBoxModel) 648: ((MutableComboBoxModel) dataModel).removeElementAt(index); 649: else 650: throw new RuntimeException("Unable to remove the item because the data " 651: + "model it is not an instance of " 652: + "MutableComboBoxModel."); 653: } 654: 655: /** 656: * This method removes all elements from this JComboBox. 657: * <p> 658: * A <code>RuntimeException</code> is thrown if the data model is not an 659: * instance of {@link MutableComboBoxModel}. 660: * </p> 661: */ 662: public void removeAllItems() 663: { 664: if (dataModel instanceof DefaultComboBoxModel) 665: // Uses special method if we have a DefaultComboBoxModel. 666: ((DefaultComboBoxModel) dataModel).removeAllElements(); 667: else if (dataModel instanceof MutableComboBoxModel) 668: { 669: // Iterates over all items and removes each. 670: MutableComboBoxModel mcbm = (MutableComboBoxModel) dataModel; 671: 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); 676: } 677: else 678: throw new RuntimeException("Unable to remove the items because the data " 679: + "model it is not an instance of " 680: + "MutableComboBoxModel."); 681: } 682: 683: /** 684: * This method displays popup with list of combo box's items on the screen 685: */ 686: public void showPopup() 687: { 688: setPopupVisible(true); 689: } 690: 691: /** 692: * This method hides popup containing list of combo box's items 693: */ 694: public void hidePopup() 695: { 696: setPopupVisible(false); 697: } 698: 699: /** 700: * This method either displayes or hides the popup containing list of combo 701: * box's items. 702: * 703: * @param visible show popup if 'visible' is true and hide it otherwise 704: */ 705: public void setPopupVisible(boolean visible) 706: { 707: getUI().setPopupVisible(this, visible); 708: } 709: 710: /** 711: * Checks if popup is currently visible on the screen. 712: * 713: * @return boolean true if popup is visible and false otherwise 714: */ 715: public boolean isPopupVisible() 716: { 717: return getUI().isPopupVisible(this); 718: } 719: 720: /** 721: * This method sets actionCommand to the specified string. ActionEvent fired 722: * to this JComboBox registered ActionListeners will contain this 723: * actionCommand. 724: * 725: * @param aCommand new action command for the JComboBox's ActionEvent 726: */ 727: public void setActionCommand(String aCommand) 728: { 729: actionCommand = aCommand; 730: } 731: 732: /** 733: * Returns actionCommand associated with the ActionEvent fired by the 734: * JComboBox to its registered ActionListeners. 735: * 736: * @return String actionCommand for the ActionEvent 737: */ 738: public String getActionCommand() 739: { 740: return actionCommand; 741: } 742: 743: /** 744: * setAction 745: * 746: * @param a action to set 747: */ 748: public void setAction(Action a) 749: { 750: Action old = action; 751: action = a; 752: configurePropertiesFromAction(action); 753: if (action != null) 754: // FIXME: remove from old action and add to new action 755: // PropertyChangeListener to listen to changes in the action 756: addActionListener(action); 757: } 758: 759: /** 760: * This method returns Action that is invoked when selected item is changed 761: * in the JComboBox. 762: * 763: * @return Action 764: */ 765: public Action getAction() 766: { 767: return action; 768: } 769: 770: /** 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. 774: * 775: * @param a An Action to configure the combo box from 776: */ 777: protected void configurePropertiesFromAction(Action a) 778: { 779: if (a == null) 780: { 781: setEnabled(true); 782: setToolTipText(null); 783: } 784: else 785: { 786: setEnabled(a.isEnabled()); 787: setToolTipText((String) (a.getValue(Action.SHORT_DESCRIPTION))); 788: } 789: } 790: 791: /** 792: * Creates PropertyChangeListener to listen for the changes in comboBox's 793: * action properties. 794: * 795: * @param action action to listen to for property changes 796: * 797: * @return a PropertyChangeListener that listens to changes in 798: * action properties. 799: */ 800: protected PropertyChangeListener createActionPropertyChangeListener(Action action) 801: { 802: return new PropertyChangeListener() 803: { 804: public void propertyChange(PropertyChangeEvent e) 805: { 806: Action act = (Action) (e.getSource()); 807: configurePropertiesFromAction(act); 808: } 809: }; 810: } 811: 812: /** 813: * This method fires ItemEvent to this JComboBox's registered ItemListeners. 814: * This method is invoked when currently selected item in this combo box 815: * has changed. 816: * 817: * @param e the ItemEvent describing the change in the combo box's 818: * selection. 819: */ 820: protected void fireItemStateChanged(ItemEvent e) 821: { 822: ItemListener[] ll = getItemListeners(); 823: 824: for (int i = 0; i < ll.length; i++) 825: ll[i].itemStateChanged(e); 826: } 827: 828: /** 829: * This method fires ActionEvent to this JComboBox's registered 830: * ActionListeners. This method is invoked when user explicitly changes 831: * currently selected item. 832: */ 833: protected void fireActionEvent() 834: { 835: ActionListener[] ll = getActionListeners(); 836: 837: for (int i = 0; i < ll.length; i++) 838: ll[i].actionPerformed(new ActionEvent(this, 839: ActionEvent.ACTION_PERFORMED, 840: actionCommand)); 841: } 842: 843: /** 844: * Fires a popupMenuCanceled() event to all <code>PopupMenuListeners</code>. 845: * 846: * Note: This method is intended for use by plaf classes only. 847: */ 848: public void firePopupMenuCanceled() 849: { 850: PopupMenuListener[] listeners = getPopupMenuListeners(); 851: PopupMenuEvent e = new PopupMenuEvent(this); 852: for (int i = 0; i < listeners.length; i++) 853: listeners[i].popupMenuCanceled(e); 854: } 855: 856: /** 857: * Fires a popupMenuWillBecomeInvisible() event to all 858: * <code>PopupMenuListeners</code>. 859: * 860: * Note: This method is intended for use by plaf classes only. 861: */ 862: public void firePopupMenuWillBecomeInvisible() 863: { 864: PopupMenuListener[] listeners = getPopupMenuListeners(); 865: PopupMenuEvent e = new PopupMenuEvent(this); 866: for (int i = 0; i < listeners.length; i++) 867: listeners[i].popupMenuWillBecomeInvisible(e); 868: } 869: 870: /** 871: * Fires a popupMenuWillBecomeVisible() event to all 872: * <code>PopupMenuListeners</code>. 873: * 874: * Note: This method is intended for use by plaf classes only. 875: */ 876: public void firePopupMenuWillBecomeVisible() 877: { 878: PopupMenuListener[] listeners = getPopupMenuListeners(); 879: PopupMenuEvent e = new PopupMenuEvent(this); 880: for (int i = 0; i < listeners.length; i++) 881: listeners[i].popupMenuWillBecomeVisible(e); 882: } 883: 884: /** 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 888: * the change. 889: */ 890: protected void selectedItemChanged() 891: { 892: // Fire ItemEvent to indicated that previously selected item is now 893: // deselected 894: if (selectedItemReminder != null) 895: fireItemStateChanged(new ItemEvent(this, ItemEvent.ITEM_STATE_CHANGED, 896: selectedItemReminder, 897: ItemEvent.DESELECTED)); 898: 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)); 904: 905: // Fire Action Event to JComboBox's registered listeners 906: fireActionEvent(); 907: 908: selectedItemReminder = newSelection; 909: } 910: 911: /** 912: * Returns Object array of size 1 containing currently selected element in 913: * the JComboBox. 914: * 915: * @return Object[] Object array of size 1 containing currently selected 916: * element in the JComboBox. 917: */ 918: public Object[] getSelectedObjects() 919: { 920: return new Object[] { getSelectedItem() }; 921: } 922: 923: /** 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. 927: * 928: * @param e the ActionEvent 929: */ 930: public void actionPerformed(ActionEvent e) 931: { 932: setSelectedItem(getEditor().getItem()); 933: setPopupVisible(false); 934: } 935: 936: /** 937: * This method selects item in this combo box that matches specified 938: * specified keyChar and returns true if such item is found. Otherwise 939: * false is returned. 940: * 941: * @param keyChar character indicating which item in the combo box should be 942: * selected. 943: * 944: * @return boolean true if item corresponding to the specified keyChar 945: * exists in the combo box. Otherwise false is returned. 946: */ 947: public boolean selectWithKeyChar(char keyChar) 948: { 949: if (keySelectionManager == null) 950: { 951: keySelectionManager = createDefaultKeySelectionManager(); 952: } 953: 954: int index = keySelectionManager.selectionForKey(keyChar, getModel());