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