/* |
|
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. |
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
|
* |
|
* This code is free software; you can redistribute it and/or modify it |
|
* under the terms of the GNU General Public License version 2 only, as |
|
* published by the Free Software Foundation. Oracle designates this |
|
* particular file as subject to the "Classpath" exception as provided |
|
* by Oracle in the LICENSE file that accompanied this code. |
|
* |
|
* This code is distributed in the hope that it will be useful, but WITHOUT |
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
* version 2 for more details (a copy is included in the LICENSE file that |
|
* accompanied this code). |
|
* |
|
* You should have received a copy of the GNU General Public License version |
|
* 2 along with this work; if not, write to the Free Software Foundation, |
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
* |
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
* or visit www.oracle.com if you need additional information or have any |
|
* questions. |
|
*/ |
|
package javax.swing; |
|
import java.beans.PropertyChangeEvent; |
|
import java.beans.PropertyChangeListener; |
|
import java.beans.Transient; |
|
import java.util.*; |
|
import java.awt.*; |
|
import java.awt.event.*; |
|
import java.io.Serializable; |
|
import java.io.ObjectOutputStream; |
|
import java.io.IOException; |
|
import javax.swing.event.*; |
|
import javax.swing.plaf.*; |
|
import javax.accessibility.*; |
|
/** |
|
* A component that combines a button or editable field and a drop-down list. |
|
* The user can select a value from the drop-down list, which appears at the |
|
* user's request. If you make the combo box editable, then the combo box |
|
* includes an editable field into which the user can type a value. |
|
* <p> |
|
* <strong>Warning:</strong> Swing is not thread safe. For more |
|
* information see <a |
|
* href="package-summary.html#threading">Swing's Threading |
|
* Policy</a>. |
|
* <p> |
|
* <strong>Warning:</strong> |
|
* Serialized objects of this class will not be compatible with |
|
* future Swing releases. The current serialization support is |
|
* appropriate for short term storage or RMI between applications running |
|
* the same version of Swing. As of 1.4, support for long term storage |
|
* of all JavaBeans™ |
|
* has been added to the <code>java.beans</code> package. |
|
* Please see {@link java.beans.XMLEncoder}. |
|
* |
|
* <p> |
|
* See <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/combobox.html">How to Use Combo Boxes</a> |
|
* in <a href="https://docs.oracle.com/javase/tutorial/"><em>The Java Tutorial</em></a> |
|
* for further information. |
|
* <p> |
|
* @see ComboBoxModel |
|
* @see DefaultComboBoxModel |
|
* |
|
* @param <E> the type of the elements of this combo box |
|
* |
|
* @beaninfo |
|
* attribute: isContainer false |
|
* description: A combination of a text field and a drop-down list. |
|
* |
|
* @author Arnaud Weber |
|
* @author Mark Davidson |
|
*/ |
|
public class JComboBox<E> extends JComponent |
|
implements ItemSelectable,ListDataListener,ActionListener, Accessible { |
|
/** |
|
* @see #getUIClassID |
|
* @see #readObject |
|
*/ |
|
private static final String uiClassID = "ComboBoxUI"; |
|
/** |
|
* This protected field is implementation specific. Do not access directly |
|
* or override. Use the accessor methods instead. |
|
* |
|
* @see #getModel |
|
* @see #setModel |
|
*/ |
|
protected ComboBoxModel<E> dataModel; |
|
/** |
|
* This protected field is implementation specific. Do not access directly |
|
* or override. Use the accessor methods instead. |
|
* |
|
* @see #getRenderer |
|
* @see #setRenderer |
|
*/ |
|
protected ListCellRenderer<? super E> renderer; |
|
/** |
|
* This protected field is implementation specific. Do not access directly |
|
* or override. Use the accessor methods instead. |
|
* |
|
* @see #getEditor |
|
* @see #setEditor |
|
*/ |
|
protected ComboBoxEditor editor; |
|
/** |
|
* This protected field is implementation specific. Do not access directly |
|
* or override. Use the accessor methods instead. |
|
* |
|
* @see #getMaximumRowCount |
|
* @see #setMaximumRowCount |
|
*/ |
|
protected int maximumRowCount = 8; |
|
/** |
|
* This protected field is implementation specific. Do not access directly |
|
* or override. Use the accessor methods instead. |
|
* |
|
* @see #isEditable |
|
* @see #setEditable |
|
*/ |
|
protected boolean isEditable = false; |
|
/** |
|
* This protected field is implementation specific. Do not access directly |
|
* or override. Use the accessor methods instead. |
|
* |
|
* @see #setKeySelectionManager |
|
* @see #getKeySelectionManager |
|
*/ |
|
protected KeySelectionManager keySelectionManager = null; |
|
/** |
|
* This protected field is implementation specific. Do not access directly |
|
* or override. Use the accessor methods instead. |
|
* |
|
* @see #setActionCommand |
|
* @see #getActionCommand |
|
*/ |
|
protected String actionCommand = "comboBoxChanged"; |
|
/** |
|
* This protected field is implementation specific. Do not access directly |
|
* or override. Use the accessor methods instead. |
|
* |
|
* @see #setLightWeightPopupEnabled |
|
* @see #isLightWeightPopupEnabled |
|
*/ |
|
protected boolean lightWeightPopupEnabled = JPopupMenu.getDefaultLightWeightPopupEnabled(); |
|
/** |
|
* This protected field is implementation specific. Do not access directly |
|
* or override. |
|
*/ |
|
protected Object selectedItemReminder = null; |
|
private E prototypeDisplayValue; |
|
// Flag to ensure that infinite loops do not occur with ActionEvents. |
|
private boolean firingActionEvent = false; |
|
// Flag to ensure the we don't get multiple ActionEvents on item selection. |
|
private boolean selectingItem = false; |
|
/** |
|
* Creates a <code>JComboBox</code> that takes its items from an |
|
* existing <code>ComboBoxModel</code>. Since the |
|
* <code>ComboBoxModel</code> is provided, a combo box created using |
|
* this constructor does not create a default combo box model and |
|
* may impact how the insert, remove and add methods behave. |
|
* |
|
* @param aModel the <code>ComboBoxModel</code> that provides the |
|
* displayed list of items |
|
* @see DefaultComboBoxModel |
|
*/ |
|
public JComboBox(ComboBoxModel<E> aModel) { |
|
super(); |
|
setModel(aModel); |
|
init(); |
|
} |
|
/** |
|
* Creates a <code>JComboBox</code> that contains the elements |
|
* in the specified array. By default the first item in the array |
|
* (and therefore the data model) becomes selected. |
|
* |
|
* @param items an array of objects to insert into the combo box |
|
* @see DefaultComboBoxModel |
|
*/ |
|
public JComboBox(E[] items) { |
|
super(); |
|
setModel(new DefaultComboBoxModel<E>(items)); |
|
init(); |
|
} |
|
/** |
|
* Creates a <code>JComboBox</code> that contains the elements |
|
* in the specified Vector. By default the first item in the vector |
|
* (and therefore the data model) becomes selected. |
|
* |
|
* @param items an array of vectors to insert into the combo box |
|
* @see DefaultComboBoxModel |
|
*/ |
|
public JComboBox(Vector<E> items) { |
|
super(); |
|
setModel(new DefaultComboBoxModel<E>(items)); |
|
init(); |
|
} |
|
/** |
|
* Creates a <code>JComboBox</code> with a default data model. |
|
* The default data model is an empty list of objects. |
|
* Use <code>addItem</code> to add items. By default the first item |
|
* in the data model becomes selected. |
|
* |
|
* @see DefaultComboBoxModel |
|
*/ |
|
public JComboBox() { |
|
super(); |
|
setModel(new DefaultComboBoxModel<E>()); |
|
init(); |
|
} |
|
private void init() { |
|
installAncestorListener(); |
|
setUIProperty("opaque",true); |
|
updateUI(); |
|
} |
|
protected void installAncestorListener() { |
|
addAncestorListener(new AncestorListener(){ |
|
public void ancestorAdded(AncestorEvent event){ hidePopup();} |
|
public void ancestorRemoved(AncestorEvent event){ hidePopup();} |
|
public void ancestorMoved(AncestorEvent event){ |
|
if (event.getSource() != JComboBox.this) |
|
hidePopup(); |
|
}}); |
|
} |
|
/** |
|
* Sets the L&F object that renders this component. |
|
* |
|
* @param ui the <code>ComboBoxUI</code> L&F object |
|
* @see UIDefaults#getUI |
|
* |
|
* @beaninfo |
|
* bound: true |
|
* hidden: true |
|
* attribute: visualUpdate true |
|
* description: The UI object that implements the Component's LookAndFeel. |
|
*/ |
|
public void setUI(ComboBoxUI ui) { |
|
super.setUI(ui); |
|
} |
|
/** |
|
* Resets the UI property to a value from the current look and feel. |
|
* |
|
* @see JComponent#updateUI |
|
*/ |
|
public void updateUI() { |
|
setUI((ComboBoxUI)UIManager.getUI(this)); |
|
ListCellRenderer<? super E> renderer = getRenderer(); |
|
if (renderer instanceof Component) { |
|
SwingUtilities.updateComponentTreeUI((Component)renderer); |
|
} |
|
} |
|
/** |
|
* Returns the name of the L&F class that renders this component. |
|
* |
|
* @return the string "ComboBoxUI" |
|
* @see JComponent#getUIClassID |
|
* @see UIDefaults#getUI |
|
*/ |
|
public String getUIClassID() { |
|
return uiClassID; |
|
} |
|
/** |
|
* Returns the L&F object that renders this component. |
|
* |
|
* @return the ComboBoxUI object that renders this component |
|
*/ |
|
public ComboBoxUI getUI() { |
|
return(ComboBoxUI)ui; |
|
} |
|
/** |
|
* Sets the data model that the <code>JComboBox</code> uses to obtain |
|
* the list of items. |
|
* |
|
* @param aModel the <code>ComboBoxModel</code> that provides the |
|
* displayed list of items |
|
* |
|
* @beaninfo |
|
* bound: true |
|
* description: Model that the combo box uses to get data to display. |
|
*/ |
|
public void setModel(ComboBoxModel<E> aModel) { |
|
ComboBoxModel<E> oldModel = dataModel; |
|
if (oldModel != null) { |
|
oldModel.removeListDataListener(this); |
|
} |
|
dataModel = aModel; |
|
dataModel.addListDataListener(this); |
|
// set the current selected item. |
|
selectedItemReminder = dataModel.getSelectedItem(); |
|
firePropertyChange( "model", oldModel, dataModel); |
|
} |
|
/** |
|
* Returns the data model currently used by the <code>JComboBox</code>. |
|
* |
|
* @return the <code>ComboBoxModel</code> that provides the displayed |
|
* list of items |
|
*/ |
|
public ComboBoxModel<E> getModel() { |
|
return dataModel; |
|
} |
|
/* |
|
* Properties |
|
*/ |
|
/** |
|
* Sets the <code>lightWeightPopupEnabled</code> property, which |
|
* provides a hint as to whether or not a lightweight |
|
* <code>Component</code> should be used to contain the |
|
* <code>JComboBox</code>, versus a heavyweight |
|
* <code>Component</code> such as a <code>Panel</code> |
|
* or a <code>Window</code>. The decision of lightweight |
|
* versus heavyweight is ultimately up to the |
|
* <code>JComboBox</code>. Lightweight windows are more |
|
* efficient than heavyweight windows, but lightweight |
|
* and heavyweight components do not mix well in a GUI. |
|
* If your application mixes lightweight and heavyweight |
|
* components, you should disable lightweight popups. |
|
* The default value for the <code>lightWeightPopupEnabled</code> |
|
* property is <code>true</code>, unless otherwise specified |
|
* by the look and feel. Some look and feels always use |
|
* heavyweight popups, no matter what the value of this property. |
|
* <p> |
|
* See the article <a href="http://www.oracle.com/technetwork/articles/java/mixing-components-433992.html">Mixing Heavy and Light Components</a> |
|
* This method fires a property changed event. |
|
* |
|
* @param aFlag if <code>true</code>, lightweight popups are desired |
|
* |
|
* @beaninfo |
|
* bound: true |
|
* expert: true |
|
* description: Set to <code>false</code> to require heavyweight popups. |
|
*/ |
|
public void setLightWeightPopupEnabled(boolean aFlag) { |
|
boolean oldFlag = lightWeightPopupEnabled; |
|
lightWeightPopupEnabled = aFlag; |
|
firePropertyChange("lightWeightPopupEnabled", oldFlag, lightWeightPopupEnabled); |
|
} |
|
/** |
|
* Gets the value of the <code>lightWeightPopupEnabled</code> |
|
* property. |
|
* |
|
* @return the value of the <code>lightWeightPopupEnabled</code> |
|
* property |
|
* @see #setLightWeightPopupEnabled |
|
*/ |
|
public boolean isLightWeightPopupEnabled() { |
|
return lightWeightPopupEnabled; |
|
} |
|
/** |
|
* Determines whether the <code>JComboBox</code> field is editable. |
|
* An editable <code>JComboBox</code> allows the user to type into the |
|
* field or selected an item from the list to initialize the field, |
|
* after which it can be edited. (The editing affects only the field, |
|
* the list item remains intact.) A non editable <code>JComboBox</code> |
|
* displays the selected item in the field, |
|
* but the selection cannot be modified. |
|
* |
|
* @param aFlag a boolean value, where true indicates that the |
|
* field is editable |
|
* |
|
* @beaninfo |
|
* bound: true |
|
* preferred: true |
|
* description: If true, the user can type a new value in the combo box. |
|
*/ |
|
public void setEditable(boolean aFlag) { |
|
boolean oldFlag = isEditable; |
|
isEditable = aFlag; |
|
firePropertyChange( "editable", oldFlag, isEditable ); |
|
} |
|
/** |
|
* Returns true if the <code>JComboBox</code> is editable. |
|
* By default, a combo box is not editable. |
|
* |
|
* @return true if the <code>JComboBox</code> is editable, else false |
|
*/ |
|
public boolean isEditable() { |
|
return isEditable; |
|
} |
|
/** |
|
* Sets the maximum number of rows the <code>JComboBox</code> displays. |
|
* If the number of objects in the model is greater than count, |
|
* the combo box uses a scrollbar. |
|
* |
|
* @param count an integer specifying the maximum number of items to |
|
* display in the list before using a scrollbar |
|
* @beaninfo |
|
* bound: true |
|
* preferred: true |
|
* description: The maximum number of rows the popup should have |
|
*/ |
|
public void setMaximumRowCount(int count) { |
|
int oldCount = maximumRowCount; |
|
maximumRowCount = count; |
|
firePropertyChange( "maximumRowCount", oldCount, maximumRowCount ); |
|
} |
|
/** |
|
* Returns the maximum number of items the combo box can display |
|
* without a scrollbar |
|
* |
|
* @return an integer specifying the maximum number of items that are |
|
* displayed in the list before using a scrollbar |
|
*/ |
|
public int getMaximumRowCount() { |
|
return maximumRowCount; |
|
} |
|
/** |
|
* Sets the renderer that paints the list items and the item selected from the list in |
|
* the JComboBox field. The renderer is used if the JComboBox is not |
|
* editable. If it is editable, the editor is used to render and edit |
|
* the selected item. |
|
* <p> |
|
* The default renderer displays a string or an icon. |
|
* Other renderers can handle graphic images and composite items. |
|
* <p> |
|
* To display the selected item, |
|
* <code>aRenderer.getListCellRendererComponent</code> |
|
* is called, passing the list object and an index of -1. |
|
* |
|
* @param aRenderer the <code>ListCellRenderer</code> that |
|
* displays the selected item |
|
* @see #setEditor |
|
* @beaninfo |
|
* bound: true |
|
* expert: true |
|
* description: The renderer that paints the item selected in the list. |
|
*/ |
|
public void setRenderer(ListCellRenderer<? super E> aRenderer) { |
|
ListCellRenderer<? super E> oldRenderer = renderer; |
|
renderer = aRenderer; |
|
firePropertyChange( "renderer", oldRenderer, renderer ); |
|
invalidate(); |
|
} |
|
/** |
|
* Returns the renderer used to display the selected item in the |
|
* <code>JComboBox</code> field. |
|
* |
|
* @return the <code>ListCellRenderer</code> that displays |
|
* the selected item. |
|
*/ |
|
public ListCellRenderer<? super E> getRenderer() { |
|
return renderer; |
|
} |
|
/** |
|
* Sets the editor used to paint and edit the selected item in the |
|
* <code>JComboBox</code> field. The editor is used only if the |
|
* receiving <code>JComboBox</code> is editable. If not editable, |
|
* the combo box uses the renderer to paint the selected item. |
|
* |
|
* @param anEditor the <code>ComboBoxEditor</code> that |
|
* displays the selected item |
|
* @see #setRenderer |
|
* @beaninfo |
|
* bound: true |
|
* expert: true |
|
* description: The editor that combo box uses to edit the current value |
|
*/ |
|
public void setEditor(ComboBoxEditor anEditor) { |
|
ComboBoxEditor oldEditor = editor; |
|
if ( editor != null ) { |
|
editor.removeActionListener(this); |
|
} |
|
editor = anEditor; |
|
if ( editor != null ) { |
|
editor.addActionListener(this); |
|
} |
|
firePropertyChange( "editor", oldEditor, editor ); |
|
} |
|
/** |
|
* Returns the editor used to paint and edit the selected item in the |
|
* <code>JComboBox</code> field. |
|
* |
|
* @return the <code>ComboBoxEditor</code> that displays the selected item |
|
*/ |
|
public ComboBoxEditor getEditor() { |
|
return editor; |
|
} |
|
// |
|
// Selection |
|
// |
|
/** |
|
* Sets the selected item in the combo box display area to the object in |
|
* the argument. |
|
* If <code>anObject</code> is in the list, the display area shows |
|
* <code>anObject</code> selected. |
|
* <p> |
|
* If <code>anObject</code> is <i>not</i> in the list and the combo box is |
|
* uneditable, it will not change the current selection. For editable |
|
* combo boxes, the selection will change to <code>anObject</code>. |
|
* <p> |
|
* If this constitutes a change in the selected item, |
|
* <code>ItemListener</code>s added to the combo box will be notified with |
|
* one or two <code>ItemEvent</code>s. |
|
* If there is a current selected item, an <code>ItemEvent</code> will be |
|
* fired and the state change will be <code>ItemEvent.DESELECTED</code>. |
|
* If <code>anObject</code> is in the list and is not currently selected |
|
* then an <code>ItemEvent</code> will be fired and the state change will |
|
* be <code>ItemEvent.SELECTED</code>. |
|
* <p> |
|
* <code>ActionListener</code>s added to the combo box will be notified |
|
* with an <code>ActionEvent</code> when this method is called. |
|
* |
|
* @param anObject the list object to select; use <code>null</code> to |
|
clear the selection |
|
* @beaninfo |
|
* preferred: true |
|
* description: Sets the selected item in the JComboBox. |
|
*/ |
|
public void setSelectedItem(Object anObject) { |
|
Object oldSelection = selectedItemReminder; |
|
Object objectToSelect = anObject; |
|
if (oldSelection == null || !oldSelection.equals(anObject)) { |
|
if (anObject != null && !isEditable()) { |
|
// For non editable combo boxes, an invalid selection |
|
// will be rejected. |
|
boolean found = false; |
|
for (int i = 0; i < dataModel.getSize(); i++) { |
|
E element = dataModel.getElementAt(i); |
|
if (anObject.equals(element)) { |
|
found = true; |
|
objectToSelect = element; |
|
break; |
|
} |
|
} |
|
if (!found) { |
|
return; |
|
} |
|
} |
|
// Must toggle the state of this flag since this method |
|
// call may result in ListDataEvents being fired. |
|
selectingItem = true; |
|
dataModel.setSelectedItem(objectToSelect); |
|
selectingItem = false; |
|
if (selectedItemReminder != dataModel.getSelectedItem()) { |
|
// in case a users implementation of ComboBoxModel |
|
// doesn't fire a ListDataEvent when the selection |
|
// changes. |
|
selectedItemChanged(); |
|
} |
|
} |
|
fireActionEvent(); |
|
} |
|
/** |
|
* Returns the current selected item. |
|
* <p> |
|
* If the combo box is editable, then this value may not have been added |
|
* to the combo box with <code>addItem</code>, <code>insertItemAt</code> |
|
* or the data constructors. |
|
* |
|
* @return the current selected Object |
|
* @see #setSelectedItem |
|
*/ |
|
public Object getSelectedItem() { |
|
return dataModel.getSelectedItem(); |
|
} |
|
/** |
|
* Selects the item at index <code>anIndex</code>. |
|
* |
|
* @param anIndex an integer specifying the list item to select, |
|
* where 0 specifies the first item in the list and -1 indicates no selection |
|
* @exception IllegalArgumentException if <code>anIndex</code> < -1 or |
|
* <code>anIndex</code> is greater than or equal to size |
|
* @beaninfo |
|
* preferred: true |
|
* description: The item at index is selected. |
|
*/ |
|
public void setSelectedIndex(int anIndex) { |
|
int size = dataModel.getSize(); |
|
if ( anIndex == -1 ) { |
|
setSelectedItem( null ); |
|
} else if ( anIndex < -1 || anIndex >= size ) { |
|
throw new IllegalArgumentException("setSelectedIndex: " + anIndex + " out of bounds"); |
|
} else { |
|
setSelectedItem(dataModel.getElementAt(anIndex)); |
|
} |
|
} |
|
/** |
|
* Returns the first item in the list that matches the given item. |
|
* The result is not always defined if the <code>JComboBox</code> |
|
* allows selected items that are not in the list. |
|
* Returns -1 if there is no selected item or if the user specified |
|
* an item which is not in the list. |
|
|
|
* @return an integer specifying the currently selected list item, |
|
* where 0 specifies |
|
* the first item in the list; |
|
* or -1 if no item is selected or if |
|
* the currently selected item is not in the list |
|
*/ |
|
@Transient |
|
public int getSelectedIndex() { |
|
Object sObject = dataModel.getSelectedItem(); |
|
int i,c; |
|
E obj; |
|
for ( i=0,c=dataModel.getSize();i<c;i++ ) { |
|
obj = dataModel.getElementAt(i); |
|
if ( obj != null && obj.equals(sObject) ) |
|
return i; |
|
} |
|
return -1; |
|
} |
|
/** |
|
* Returns the "prototypical display" value - an Object used |
|
* for the calculation of the display height and width. |
|
* |
|
* @return the value of the <code>prototypeDisplayValue</code> property |
|
* @see #setPrototypeDisplayValue |
|
* @since 1.4 |
|
*/ |
|
public E getPrototypeDisplayValue() { |
|
return prototypeDisplayValue; |
|
} |
|
/** |
|
* Sets the prototype display value used to calculate the size of the display |
|
* for the UI portion. |
|
* <p> |
|
* If a prototype display value is specified, the preferred size of |
|
* the combo box is calculated by configuring the renderer with the |
|
* prototype display value and obtaining its preferred size. Specifying |
|
* the preferred display value is often useful when the combo box will be |
|
* displaying large amounts of data. If no prototype display value has |
|
* been specified, the renderer must be configured for each value from |
|
* the model and its preferred size obtained, which can be |
|
* relatively expensive. |
|
* |
|
* @param prototypeDisplayValue |
|
* @see #getPrototypeDisplayValue |
|
* @since 1.4 |
|
* @beaninfo |
|
* bound: true |
|
* attribute: visualUpdate true |
|
* description: The display prototype value, used to compute display width and height. |
|
*/ |
|
public void setPrototypeDisplayValue(E prototypeDisplayValue) { |
|
Object oldValue = this.prototypeDisplayValue; |
|
this.prototypeDisplayValue = prototypeDisplayValue; |
|
firePropertyChange("prototypeDisplayValue", oldValue, prototypeDisplayValue); |
|
} |
|
/** |
|
* Adds an item to the item list. |
|
* This method works only if the <code>JComboBox</code> uses a |
|
* mutable data model. |
|
* <p> |
|
* <strong>Warning:</strong> |
|
* Focus and keyboard navigation problems may arise if you add duplicate |
|
* String objects. A workaround is to add new objects instead of String |
|
* objects and make sure that the toString() method is defined. |
|
* For example: |
|
* <pre> |
|
* comboBox.addItem(makeObj("Item 1")); |
|
* comboBox.addItem(makeObj("Item 1")); |
|
* ... |
|
* private Object makeObj(final String item) { |
|
* return new Object() { public String toString() { return item; } }; |
|
* } |
|
* </pre> |
|
* |
|
* @param item the item to add to the list |
|
* @see MutableComboBoxModel |
|
*/ |
|
public void addItem(E item) { |
|
checkMutableComboBoxModel(); |
|
((MutableComboBoxModel<E>)dataModel).addElement(item); |
|
} |
|
/** |
|
* Inserts an item into the item list at a given index. |
|
* This method works only if the <code>JComboBox</code> uses a |
|
* mutable data model. |
|
* |
|
* @param item the item to add to the list |
|
* @param index an integer specifying the position at which |
|
* to add the item |
|
* @see MutableComboBoxModel |
|
*/ |
|
public void insertItemAt(E item, int index) { |
|
checkMutableComboBoxModel(); |
|
((MutableComboBoxModel<E>)dataModel).insertElementAt(item,index); |
|
} |
|
/** |
|
* Removes an item from the item list. |
|
* This method works only if the <code>JComboBox</code> uses a |
|
* mutable data model. |
|
* |
|
* @param anObject the object to remove from the item list |
|
* @see MutableComboBoxModel |
|
*/ |
|
public void removeItem(Object anObject) { |
|
checkMutableComboBoxModel(); |
|
((MutableComboBoxModel)dataModel).removeElement(anObject); |
|
} |
|
/** |
|
* Removes the item at <code>anIndex</code> |
|
* This method works only if the <code>JComboBox</code> uses a |
|
* mutable data model. |
|
* |
|
* @param anIndex an int specifying the index of the item to remove, |
|
* where 0 |
|
* indicates the first item in the list |
|
* @see MutableComboBoxModel |
|
*/ |
|
public void removeItemAt(int anIndex) { |
|
checkMutableComboBoxModel(); |
|
((MutableComboBoxModel<E>)dataModel).removeElementAt( anIndex ); |
|
} |
|
/** |
|
* Removes all items from the item list. |
|
*/ |
|
public void removeAllItems() { |
|
checkMutableComboBoxModel(); |
|
MutableComboBoxModel<E> model = (MutableComboBoxModel<E>)dataModel; |
|
int size = model.getSize(); |
|
if ( model instanceof DefaultComboBoxModel ) { |
|
((DefaultComboBoxModel)model).removeAllElements(); |
|
} |
|
else { |
|
for ( int i = 0; i < size; ++i ) { |
|
E element = model.getElementAt( 0 ); |
|
model.removeElement( element ); |
|
} |
|
} |
|
selectedItemReminder = null; |
|
if (isEditable()) { |
|
editor.setItem(null); |
|
} |
|
} |
|
/** |
|
* Checks that the <code>dataModel</code> is an instance of |
|
* <code>MutableComboBoxModel</code>. If not, it throws an exception. |
|
* @exception RuntimeException if <code>dataModel</code> is not an |
|
* instance of <code>MutableComboBoxModel</code>. |
|
*/ |
|
void checkMutableComboBoxModel() { |
|
if ( !(dataModel instanceof MutableComboBoxModel) ) |
|
throw new RuntimeException("Cannot use this method with a non-Mutable data model."); |
|
} |
|
/** |
|
* Causes the combo box to display its popup window. |
|
* @see #setPopupVisible |
|
*/ |
|
public void showPopup() { |
|
setPopupVisible(true); |
|
} |
|
/** |
|
* Causes the combo box to close its popup window. |
|
* @see #setPopupVisible |
|
*/ |
|
public void hidePopup() { |
|
setPopupVisible(false); |
|
} |
|
/** |
|
* Sets the visibility of the popup. |
|
*/ |
|
public void setPopupVisible(boolean v) { |
|
getUI().setPopupVisible(this, v); |
|
} |
|
/** |
|
* Determines the visibility of the popup. |
|
* |
|
* @return true if the popup is visible, otherwise returns false |
|
*/ |
|
public boolean isPopupVisible() { |
|
return getUI().isPopupVisible(this); |
|
} |
|
/** Selection **/ |
|
/** |
|
* Adds an <code>ItemListener</code>. |
|
* <p> |
|
* <code>aListener</code> will receive one or two <code>ItemEvent</code>s when |
|
* the selected item changes. |
|
* |
|
* @param aListener the <code>ItemListener</code> that is to be notified |
|
* @see #setSelectedItem |
|
*/ |
|
public void addItemListener(ItemListener aListener) { |
|
listenerList.add(ItemListener.class,aListener); |
|
} |
|
/** Removes an <code>ItemListener</code>. |
|
* |
|
* @param aListener the <code>ItemListener</code> to remove |
|
*/ |
|
public void removeItemListener(ItemListener aListener) { |
|
listenerList.remove(ItemListener.class,aListener); |
|
} |
|
/** |
|
* Returns an array of all the <code>ItemListener</code>s added |
|
* to this JComboBox with addItemListener(). |
|
* |
|
* @return all of the <code>ItemListener</code>s added or an empty |
|
* array if no listeners have been added |
|
* @since 1.4 |
|
*/ |
|
public ItemListener[] getItemListeners() { |
|
return listenerList.getListeners(ItemListener.class); |
|
} |
|
/** |
|
* Adds an <code>ActionListener</code>. |
|
* <p> |
|
* The <code>ActionListener</code> will receive an <code>ActionEvent</code> |
|
* when a selection has been made. If the combo box is editable, then |
|
* an <code>ActionEvent</code> will be fired when editing has stopped. |
|
* |
|
* @param l the <code>ActionListener</code> that is to be notified |
|
* @see #setSelectedItem |
|
*/ |
|
public void addActionListener(ActionListener l) { |
|
listenerList.add(ActionListener.class,l); |
|
} |
|
/** Removes an <code>ActionListener</code>. |
|
* |
|
* @param l the <code>ActionListener</code> to remove |
|
*/ |
|
public void removeActionListener(ActionListener l) { |
|
if ((l != null) && (getAction() == l)) { |
|
setAction(null); |
|
} else { |
|
listenerList.remove(ActionListener.class, l); |
|
} |
|
} |
|
/** |
|
* Returns an array of all the <code>ActionListener</code>s added |
|
* to this JComboBox with addActionListener(). |
|
* |
|
* @return all of the <code>ActionListener</code>s added or an empty |
|
* array if no listeners have been added |
|
* @since 1.4 |
|
*/ |
|
public ActionListener[] getActionListeners() { |
|
return listenerList.getListeners(ActionListener.class); |
|
} |
|
/** |
|
* Adds a <code>PopupMenu</code> listener which will listen to notification |
|
* messages from the popup portion of the combo box. |
|
* <p> |
|
* For all standard look and feels shipped with Java, the popup list |
|
* portion of combo box is implemented as a <code>JPopupMenu</code>. |
|
* A custom look and feel may not implement it this way and will |
|
* therefore not receive the notification. |
|
* |
|
* @param l the <code>PopupMenuListener</code> to add |
|
* @since 1.4 |
|
*/ |
|
public void addPopupMenuListener(PopupMenuListener l) { |
|
listenerList.add(PopupMenuListener.class,l); |
|
} |
|
/** |
|
* Removes a <code>PopupMenuListener</code>. |
|
* |
|
* @param l the <code>PopupMenuListener</code> to remove |
|
* @see #addPopupMenuListener |
|
* @since 1.4 |
|
*/ |
|
public void removePopupMenuListener(PopupMenuListener l) { |
|
listenerList.remove(PopupMenuListener.class,l); |
|
} |
|
/** |
|
* Returns an array of all the <code>PopupMenuListener</code>s added |
|
* to this JComboBox with addPopupMenuListener(). |
|
* |
|
* @return all of the <code>PopupMenuListener</code>s added or an empty |
|
* array if no listeners have been added |
|
* @since 1.4 |
|
*/ |
|
public PopupMenuListener[] getPopupMenuListeners() { |
|
return listenerList.getListeners(PopupMenuListener.class); |
|
} |
|
/** |
|
* Notifies <code>PopupMenuListener</code>s that the popup portion of the |
|
* combo box will become visible. |
|
* <p> |
|
* This method is public but should not be called by anything other than |
|
* the UI delegate. |
|
* @see #addPopupMenuListener |
|
* @since 1.4 |
|
*/ |
|
public void firePopupMenuWillBecomeVisible() { |
|
Object[] listeners = listenerList.getListenerList(); |
|
PopupMenuEvent e=null; |
|
for (int i = listeners.length-2; i>=0; i-=2) { |
|
if (listeners[i]==PopupMenuListener.class) { |
|
if (e == null) |
|
e = new PopupMenuEvent(this); |
|
((PopupMenuListener)listeners[i+1]).popupMenuWillBecomeVisible(e); |
|
} |
|
} |
|
} |
|
/** |
|
* Notifies <code>PopupMenuListener</code>s that the popup portion of the |
|
* combo box has become invisible. |
|
* <p> |
|
* This method is public but should not be called by anything other than |
|
* the UI delegate. |
|
* @see #addPopupMenuListener |
|
* @since 1.4 |
|
*/ |
|
public void firePopupMenuWillBecomeInvisible() { |
|
Object[] listeners = listenerList.getListenerList(); |
|
PopupMenuEvent e=null; |
|
for (int i = listeners.length-2; i>=0; i-=2) { |
|
if (listeners[i]==PopupMenuListener.class) { |
|
if (e == null) |
|
e = new PopupMenuEvent(this); |
|
((PopupMenuListener)listeners[i+1]).popupMenuWillBecomeInvisible(e); |
|
} |
|
} |
|
} |
|
/** |
|
* Notifies <code>PopupMenuListener</code>s that the popup portion of the |
|
* combo box has been canceled. |
|
* <p> |
|
* This method is public but should not be called by anything other than |
|
* the UI delegate. |
|
* @see #addPopupMenuListener |
|
* @since 1.4 |
|
*/ |
|
public void firePopupMenuCanceled() { |
|
Object[] listeners = listenerList.getListenerList(); |
|
PopupMenuEvent e=null; |
|
for (int i = listeners.length-2; i>=0; i-=2) { |
|
if (listeners[i]==PopupMenuListener.class) { |
|
if (e == null) |
|
e = new PopupMenuEvent(this); |
|
((PopupMenuListener)listeners[i+1]).popupMenuCanceled(e); |
|
} |
|
} |
|
} |
|
/** |
|
* Sets the action command that should be included in the event |
|
* sent to action listeners. |
|
* |
|
* @param aCommand a string containing the "command" that is sent |
|
* to action listeners; the same listener can then |
|
* do different things depending on the command it |
|
* receives |
|
*/ |
|
public void setActionCommand(String aCommand) { |
|
actionCommand = aCommand; |
|
} |
|
/** |
|
* Returns the action command that is included in the event sent to |
|
* action listeners. |
|
* |
|
* @return the string containing the "command" that is sent |
|
* to action listeners. |
|
*/ |
|
public String getActionCommand() { |
|
return actionCommand; |
|
} |
|
private Action action; |
|
private PropertyChangeListener actionPropertyChangeListener; |
|
/** |
|
* Sets the <code>Action</code> for the <code>ActionEvent</code> source. |
|
* The new <code>Action</code> replaces any previously set |
|
* <code>Action</code> but does not affect <code>ActionListeners</code> |
|
* independently added with <code>addActionListener</code>. |
|
* If the <code>Action</code> is already a registered |
|
* <code>ActionListener</code> for the <code>ActionEvent</code> source, |
|
* it is not re-registered. |
|
* <p> |
|
* Setting the <code>Action</code> results in immediately changing |
|
* all the properties described in <a href="Action.html#buttonActions"> |
|
* Swing Components Supporting <code>Action</code></a>. |
|
* Subsequently, the combobox's properties are automatically updated |
|
* as the <code>Action</code>'s properties change. |
|
* <p> |
|
* This method uses three other methods to set |
|
* and help track the <code>Action</code>'s property values. |
|
* It uses the <code>configurePropertiesFromAction</code> method |
|
* to immediately change the combobox's properties. |
|
* To track changes in the <code>Action</code>'s property values, |
|
* this method registers the <code>PropertyChangeListener</code> |
|
* returned by <code>createActionPropertyChangeListener</code>. The |
|
* default {@code PropertyChangeListener} invokes the |
|
* {@code actionPropertyChanged} method when a property in the |
|
* {@code Action} changes. |
|
* |
|
* @param a the <code>Action</code> for the <code>JComboBox</code>, |
|
* or <code>null</code>. |
|
* @since 1.3 |
|
* @see Action |
|
* @see #getAction |
|
* @see #configurePropertiesFromAction |
|
* @see #createActionPropertyChangeListener |
|
* @see #actionPropertyChanged |
|
* @beaninfo |
|
* bound: true |
|
* attribute: visualUpdate true |
|
* description: the Action instance connected with this ActionEvent source |
|
*/ |
|
public void setAction(Action a) { |
|
Action oldValue = getAction(); |
|
if (action==null || !action.equals(a)) { |
|
action = a; |
|
if (oldValue!=null) { |
|
removeActionListener(oldValue); |
|
oldValue.removePropertyChangeListener(actionPropertyChangeListener); |
|
actionPropertyChangeListener = null; |
|
} |
|
configurePropertiesFromAction(action); |
|
if (action!=null) { |
|
// Don't add if it is already a listener |
|
if (!isListener(ActionListener.class, action)) { |
|
addActionListener(action); |
|
} |
|
// Reverse linkage: |
|
actionPropertyChangeListener = createActionPropertyChangeListener(action); |
|
action.addPropertyChangeListener(actionPropertyChangeListener); |
|
} |
|
firePropertyChange("action", oldValue, action); |
|
} |
|
} |
|
private boolean isListener(Class c, ActionListener a) { |
|
boolean isListener = false; |
|
Object[] listeners = listenerList.getListenerList(); |
|
for (int i = listeners.length-2; i>=0; i-=2) { |
|
if (listeners[i]==c && listeners[i+1]==a) { |
|
isListener=true; |
|
} |
|
} |
|
return isListener; |
|
} |
|
/** |
|
* Returns the currently set <code>Action</code> for this |
|
* <code>ActionEvent</code> source, or <code>null</code> if no |
|
* <code>Action</code> is set. |
|
* |
|
* @return the <code>Action</code> for this <code>ActionEvent</code> |
|
* source; or <code>null</code> |
|
* @since 1.3 |
|
* @see Action |
|
* @see #setAction |
|
*/ |
|
public Action getAction() { |
|
return action; |
|
} |
|
/** |
|
* Sets the properties on this combobox to match those in the specified |
|
* <code>Action</code>. Refer to <a href="Action.html#buttonActions"> |
|
* Swing Components Supporting <code>Action</code></a> for more |
|
* details as to which properties this sets. |
|
* |
|
* @param a the <code>Action</code> from which to get the properties, |
|
* or <code>null</code> |
|
* @since 1.3 |
|
* @see Action |
|
* @see #setAction |
|
*/ |
|
protected void configurePropertiesFromAction(Action a) { |
|
AbstractAction.setEnabledFromAction(this, a); |
|
AbstractAction.setToolTipTextFromAction(this, a); |
|
setActionCommandFromAction(a); |
|
} |
|
/** |
|
* Creates and returns a <code>PropertyChangeListener</code> that is |
|
* responsible for listening for changes from the specified |
|
* <code>Action</code> and updating the appropriate properties. |
|
* <p> |
|
* <b>Warning:</b> If you subclass this do not create an anonymous |
|
* inner class. If you do the lifetime of the combobox will be tied to |
|
* that of the <code>Action</code>. |
|
* |
|
* @param a the combobox's action |
|
* @since 1.3 |
|
* @see Action |
|
* @see #setAction |
|
*/ |
|
protected PropertyChangeListener createActionPropertyChangeListener(Action a) { |
|
return new ComboBoxActionPropertyChangeListener(this, a); |
|
} |
|
/** |
|
* Updates the combobox's state in response to property changes in |
|
* associated action. This method is invoked from the |
|
* {@code PropertyChangeListener} returned from |
|
* {@code createActionPropertyChangeListener}. Subclasses do not normally |
|
* need to invoke this. Subclasses that support additional {@code Action} |
|
* properties should override this and |
|
* {@code configurePropertiesFromAction}. |
|
* <p> |
|
* Refer to the table at <a href="Action.html#buttonActions"> |
|
* Swing Components Supporting <code>Action</code></a> for a list of |
|
* the properties this method sets. |
|
* |
|
* @param action the <code>Action</code> associated with this combobox |
|
* @param propertyName the name of the property that changed |
|
* @since 1.6 |
|
* @see Action |
|
* @see #configurePropertiesFromAction |
|
*/ |
|
protected void actionPropertyChanged(Action action, String propertyName) { |
|
if (propertyName == Action.ACTION_COMMAND_KEY) { |
|
setActionCommandFromAction(action); |
|
} else if (propertyName == "enabled") { |
|
AbstractAction.setEnabledFromAction(this, action); |
|
} else if (Action.SHORT_DESCRIPTION == propertyName) { |
|
AbstractAction.setToolTipTextFromAction(this, action); |
|
} |
|
} |
|
private void setActionCommandFromAction(Action a) { |
|
setActionCommand((a != null) ? |
|
(String)a.getValue(Action.ACTION_COMMAND_KEY) : |
|
null); |
|
} |
|
private static class ComboBoxActionPropertyChangeListener |
|
extends ActionPropertyChangeListener<JComboBox<?>> { |
|
ComboBoxActionPropertyChangeListener(JComboBox<?> b, Action a) { |
|
super(b, a); |
|
} |
|
protected void actionPropertyChanged(JComboBox<?> cb, |
|
Action action, |
|
PropertyChangeEvent e) { |
|
if (AbstractAction.shouldReconfigure(e)) { |
|
cb.configurePropertiesFromAction(action); |
|
} else { |
|
cb.actionPropertyChanged(action, e.getPropertyName()); |
|
} |
|
} |
|
} |
|
/** |
|
* Notifies all listeners that have registered interest for |
|
* notification on this event type. |
|
* @param e the event of interest |
|
* |
|
* @see EventListenerList |
|
*/ |
|
protected void fireItemStateChanged(ItemEvent e) { |
|
// Guaranteed to return a non-null array |
|
Object[] listeners = listenerList.getListenerList(); |
|
// Process the listeners last to first, notifying |
|
// those that are interested in this event |
|
for ( int i = listeners.length-2; i>=0; i-=2 ) { |
|
if ( listeners[i]==ItemListener.class ) { |
|
// Lazily create the event: |
|
// if (changeEvent == null) |
|
// changeEvent = new ChangeEvent(this); |
|
((ItemListener)listeners[i+1]).itemStateChanged(e); |
|
} |
|
} |
|
} |
|
/** |
|
* Notifies all listeners that have registered interest for |
|
* notification on this event type. |
|
* |
|
* @see EventListenerList |
|
*/ |
|
protected void fireActionEvent() { |
|
if (!firingActionEvent) { |
|
// Set flag to ensure that an infinite loop is not created |
|
firingActionEvent = true; |
|
ActionEvent e = null; |
|
// Guaranteed to return a non-null array |
|
Object[] listeners = listenerList.getListenerList(); |
|
long mostRecentEventTime = EventQueue.getMostRecentEventTime(); |
|
int modifiers = 0; |
|
AWTEvent currentEvent = EventQueue.getCurrentEvent(); |
|
if (currentEvent instanceof InputEvent) { |
|
modifiers = ((InputEvent)currentEvent).getModifiers(); |
|
} else if (currentEvent instanceof ActionEvent) { |
|
modifiers = ((ActionEvent)currentEvent).getModifiers(); |
|
} |
|
// Process the listeners last to first, notifying |
|
// those that are interested in this event |
|
for ( int i = listeners.length-2; i>=0; i-=2 ) { |
|
if ( listeners[i]==ActionListener.class ) { |
|
// Lazily create the event: |
|
if ( e == null ) |
|
e = new ActionEvent(this,ActionEvent.ACTION_PERFORMED, |
|
getActionCommand(), |
|
mostRecentEventTime, modifiers); |
|
((ActionListener)listeners[i+1]).actionPerformed(e); |
|
} |
|
} |
|
firingActionEvent = false; |
|
} |
|
} |
|
/** |
|
* This protected method is implementation specific. Do not access directly |
|
* or override. |
|
*/ |
|
protected void selectedItemChanged() { |
|
if (selectedItemReminder != null ) { |
|
fireItemStateChanged(new ItemEvent(this,ItemEvent.ITEM_STATE_CHANGED, |
|
selectedItemReminder, |
|
ItemEvent.DESELECTED)); |
|
} |
|
// set the new selected item. |
|
selectedItemReminder = dataModel.getSelectedItem(); |
|
if (selectedItemReminder != null ) { |
|
fireItemStateChanged(new ItemEvent(this,ItemEvent.ITEM_STATE_CHANGED, |
|
selectedItemReminder, |
|
ItemEvent.SELECTED)); |
|
} |
|
} |
|
/** |
|
* Returns an array containing the selected item. |
|
* This method is implemented for compatibility with |
|
* <code>ItemSelectable</code>. |
|
* |
|
* @return an array of <code>Objects</code> containing one |
|
* element -- the selected item |
|
*/ |
|
public Object[] getSelectedObjects() { |
|
Object selectedObject = getSelectedItem(); |
|
if ( selectedObject == null ) |
|
return new Object[0]; |
|
else { |
|
Object result[] = new Object[1]; |
|
result[0] = selectedObject; |
|
return result; |
|
} |
|
} |
|
/** |
|
* This method is public as an implementation side effect. |
|
* do not call or override. |
|
*/ |
|
public void actionPerformed(ActionEvent e) { |
|
ComboBoxEditor editor = getEditor(); |
|
if ((editor != null) && (e != null) && (editor == e.getSource() |
|
|| editor.getEditorComponent() == e.getSource())) { |
|
setPopupVisible(false); |
|
getModel().setSelectedItem(editor.getItem()); |
|
String oldCommand = getActionCommand(); |
|
setActionCommand("comboBoxEdited"); |
|
fireActionEvent(); |
|
setActionCommand(oldCommand); |
|
} |
|
} |
|
/** |
|
* This method is public as an implementation side effect. |
|
* do not call or override. |
|
*/ |
|
public void contentsChanged(ListDataEvent e) { |
|
Object oldSelection = selectedItemReminder; |
|
Object newSelection = dataModel.getSelectedItem(); |
|
if (oldSelection == null || !oldSelection.equals(newSelection)) { |
|
selectedItemChanged(); |
|
if (!selectingItem) { |
|
fireActionEvent(); |
|
} |
|
} |
|
} |
|
/** |
|
* This method is public as an implementation side effect. |
|
* do not call or override. |
|
*/ |
|
public void intervalAdded(ListDataEvent e) { |
|
if (selectedItemReminder != dataModel.getSelectedItem()) { |
|
selectedItemChanged(); |
|
} |
|
} |
|
/** |
|
* This method is public as an implementation side effect. |
|
* do not call or override. |
|
*/ |
|
public void intervalRemoved(ListDataEvent e) { |
|
contentsChanged(e); |
|
} |
|
/** |
|
* Selects the list item that corresponds to the specified keyboard |
|
* character and returns true, if there is an item corresponding |
|
* to that character. Otherwise, returns false. |
|
* |
|
* @param keyChar a char, typically this is a keyboard key |
|
* typed by the user |
|
*/ |
|
public boolean selectWithKeyChar(char keyChar) { |
|
int index; |
|
if ( keySelectionManager == null ) |
|
keySelectionManager = createDefaultKeySelectionManager(); |
|
index = keySelectionManager.selectionForKey(keyChar,getModel()); |
|
if ( index != -1 ) { |
|
setSelectedIndex(index); |
|
return true; |
|
} |
|
else |
|
return false; |
|
} |
|
/** |
|
* Enables the combo box so that items can be selected. When the |
|
* combo box is disabled, items cannot be selected and values |
|
* cannot be typed into its field (if it is editable). |
|
* |
|
* @param b a boolean value, where true enables the component and |
|
* false disables it |
|
* @beaninfo |
|
* bound: true |
|
* preferred: true |
|
* description: Whether the combo box is enabled. |
|
*/ |
|
public void setEnabled(boolean b) { |
|
super.setEnabled(b); |
|
firePropertyChange( "enabled", !isEnabled(), isEnabled() ); |
|
} |
|
/** |
|
* Initializes the editor with the specified item. |
|
* |
|
* @param anEditor the <code>ComboBoxEditor</code> that displays |
|
* the list item in the |
|
* combo box field and allows it to be edited |
|
* @param anItem the object to display and edit in the field |
|
*/ |
|
public void configureEditor(ComboBoxEditor anEditor, Object anItem) { |
|
anEditor.setItem(anItem); |
|
} |
|
/** |
|
* Handles <code>KeyEvent</code>s, looking for the Tab key. |
|
* If the Tab key is found, the popup window is closed. |
|
* |
|
* @param e the <code>KeyEvent</code> containing the keyboard |
|
* key that was pressed |
|
*/ |
|
public void processKeyEvent(KeyEvent e) { |
|
if ( e.getKeyCode() == KeyEvent.VK_TAB ) { |
|
hidePopup(); |
|
} |
|
super.processKeyEvent(e); |
|
} |
|
/** |
|
* {@inheritDoc} |
|
*/ |
|
@Override |
|
protected boolean processKeyBinding(KeyStroke ks, KeyEvent e, int condition, boolean pressed) { |
|
if (super.processKeyBinding(ks, e, condition, pressed)) { |
|
return true; |
|
} |
|
if (!isEditable() || condition != WHEN_FOCUSED || getEditor() == null |
|
|| !Boolean.TRUE.equals(getClientProperty("JComboBox.isTableCellEditor"))) { |
|
return false; |
|
} |
|
Component editorComponent = getEditor().getEditorComponent(); |
|
if (editorComponent instanceof JComponent) { |
|
JComponent component = (JComponent) editorComponent; |
|
return component.processKeyBinding(ks, e, WHEN_FOCUSED, pressed); |
|
} |
|
return false; |
|
} |
|
/** |
|
* Sets the object that translates a keyboard character into a list |
|
* selection. Typically, the first selection with a matching first |
|
* character becomes the selected item. |
|
* |
|
* @beaninfo |
|
* expert: true |
|
* description: The objects that changes the selection when a key is pressed. |
|
*/ |
|
public void setKeySelectionManager(KeySelectionManager aManager) { |
|
keySelectionManager = aManager; |
|
} |
|
/** |
|
* Returns the list's key-selection manager. |
|
* |
|
* @return the <code>KeySelectionManager</code> currently in use |
|
*/ |
|
public KeySelectionManager getKeySelectionManager() { |
|
return keySelectionManager; |
|
} |
|
/* Accessing the model */ |
|
/** |
|
* Returns the number of items in the list. |
|
* |
|
* @return an integer equal to the number of items in the list |
|
*/ |
|
public int getItemCount() { |
|
return dataModel.getSize(); |
|
} |
|
/** |
|
* Returns the list item at the specified index. If <code>index</code> |
|
* is out of range (less than zero or greater than or equal to size) |
|
* it will return <code>null</code>. |
|
* |
|
* @param index an integer indicating the list position, where the first |
|
* item starts at zero |
|
* @return the item at that list position; or |
|
* <code>null</code> if out of range |
|
*/ |
|
public E getItemAt(int index) { |
|
return dataModel.getElementAt(index); |
|
} |
|
/** |
|
* Returns an instance of the default key-selection manager. |
|
* |
|
* @return the <code>KeySelectionManager</code> currently used by the list |
|
* @see #setKeySelectionManager |
|
*/ |
|
protected KeySelectionManager createDefaultKeySelectionManager() { |
|
return new DefaultKeySelectionManager(); |
|
} |
|
/** |
|
* The interface that defines a <code>KeySelectionManager</code>. |
|
* To qualify as a <code>KeySelectionManager</code>, |
|
* the class needs to implement the method |
|
* that identifies the list index given a character and the |
|
* combo box data model. |
|
*/ |
|
public interface KeySelectionManager { |
|
/** Given <code>aKey</code> and the model, returns the row |
|
* that should become selected. Return -1 if no match was |
|
* found. |
|
* |
|
* @param aKey a char value, usually indicating a keyboard key that |
|
* was pressed |
|
* @param aModel a ComboBoxModel -- the component's data model, containing |
|
* the list of selectable items |
|
* @return an int equal to the selected row, where 0 is the |
|
* first item and -1 is none. |
|
*/ |
|
int selectionForKey(char aKey,ComboBoxModel aModel); |
|
} |
|
class DefaultKeySelectionManager implements KeySelectionManager, Serializable { |
|
public int selectionForKey(char aKey,ComboBoxModel aModel) { |
|
int i,c; |
|
int currentSelection = -1; |
|
Object selectedItem = aModel.getSelectedItem(); |
|
String v; |
|
String pattern; |
|
if ( selectedItem != null ) { |
|
for ( i=0,c=aModel.getSize();i<c;i++ ) { |
|
if ( selectedItem == aModel.getElementAt(i) ) { |
|
currentSelection = i; |
|
break; |
|
} |
|
} |
|
} |
|
pattern = ("" + aKey).toLowerCase(); |
|
aKey = pattern.charAt(0); |
|
for ( i = ++currentSelection, c = aModel.getSize() ; i < c ; i++ ) { |
|
Object elem = aModel.getElementAt(i); |
|
if (elem != null && elem.toString() != null) { |
|
v = elem.toString().toLowerCase(); |
|
if ( v.length() > 0 && v.charAt(0) == aKey ) |
|
return i; |
|
} |
|
} |
|
for ( i = 0 ; i < currentSelection ; i ++ ) { |
|
Object elem = aModel.getElementAt(i); |
|
if (elem != null && elem.toString() != null) { |
|
v = elem.toString().toLowerCase(); |
|
if ( v.length() > 0 && v.charAt(0) == aKey ) |
|
return i; |
|
} |
|
} |
|
return -1; |
|
} |
|
} |
|
/** |
|
* See <code>readObject</code> and <code>writeObject</code> in |
|
* <code>JComponent</code> for more |
|
* information about serialization in Swing. |
|
*/ |
|
private void writeObject(ObjectOutputStream s) throws IOException { |
|
s.defaultWriteObject(); |
|
if (getUIClassID().equals(uiClassID)) { |
|
byte count = JComponent.getWriteObjCounter(this); |
|
JComponent.setWriteObjCounter(this, --count); |
|
if (count == 0 && ui != null) { |
|
ui.installUI(this); |
|
} |
|
} |
|
} |
|
/** |
|
* Returns a string representation of this <code>JComboBox</code>. |
|
* This method is intended to be used only for debugging purposes, |
|
* and the content and format of the returned string may vary between |
|
* implementations. The returned string may be empty but may not |
|
* be <code>null</code>. |
|
* |
|
* @return a string representation of this <code>JComboBox</code> |
|
*/ |
|
protected String paramString() { |
|
String selectedItemReminderString = (selectedItemReminder != null ? |
|
selectedItemReminder.toString() : |
|
""); |
|
String isEditableString = (isEditable ? "true" : "false"); |
|
String lightWeightPopupEnabledString = (lightWeightPopupEnabled ? |
|
"true" : "false"); |
|
return super.paramString() + |
|
",isEditable=" + isEditableString + |
|
",lightWeightPopupEnabled=" + lightWeightPopupEnabledString + |
|
",maximumRowCount=" + maximumRowCount + |
|
",selectedItemReminder=" + selectedItemReminderString; |
|
} |
|
/////////////////// |
|
// Accessibility support |
|
/////////////////// |
|
/** |
|
* Gets the AccessibleContext associated with this JComboBox. |
|
* For combo boxes, the AccessibleContext takes the form of an |
|
* AccessibleJComboBox. |
|
* A new AccessibleJComboBox instance is created if necessary. |
|
* |
|
* @return an AccessibleJComboBox that serves as the |
|
* AccessibleContext of this JComboBox |
|
*/ |
|
public AccessibleContext getAccessibleContext() { |
|
if ( accessibleContext == null ) { |
|
accessibleContext = new AccessibleJComboBox(); |
|
} |
|
return accessibleContext; |
|
} |
|
/** |
|
* This class implements accessibility support for the |
|
* <code>JComboBox</code> class. It provides an implementation of the |
|
* Java Accessibility API appropriate to Combo Box user-interface elements. |
|
* <p> |
|
* <strong>Warning:</strong> |
|
* Serialized objects of this class will not be compatible with |
|
* future Swing releases. The current serialization support is |
|
* appropriate for short term storage or RMI between applications running |
|
* the same version of Swing. As of 1.4, support for long term storage |
|
* of all JavaBeans™ |
|
* has been added to the <code>java.beans</code> package. |
|
* Please see {@link java.beans.XMLEncoder}. |
|
*/ |
|
protected class AccessibleJComboBox extends AccessibleJComponent |
|
implements AccessibleAction, AccessibleSelection { |
|
private JList popupList; // combo box popup list |
|
private Accessible previousSelectedAccessible = null; |
|
/** |
|
* Returns an AccessibleJComboBox instance |
|
* @since 1.4 |
|
*/ |
|
public AccessibleJComboBox() { |
|
// set the combo box editor's accessible name and description |
|
JComboBox.this.addPropertyChangeListener(new AccessibleJComboBoxPropertyChangeListener()); |
|
setEditorNameAndDescription(); |
|
// Get the popup list |
|
Accessible a = getUI().getAccessibleChild(JComboBox.this, 0); |
|
if (a instanceof javax.swing.plaf.basic.ComboPopup) { |
|
// Listen for changes to the popup menu selection. |
|
popupList = ((javax.swing.plaf.basic.ComboPopup)a).getList(); |
|
popupList.addListSelectionListener( |
|
new AccessibleJComboBoxListSelectionListener()); |
|
} |
|
// Listen for popup menu show/hide events |
|
JComboBox.this.addPopupMenuListener( |
|
new AccessibleJComboBoxPopupMenuListener()); |
|
} |
|
/* |
|
* JComboBox PropertyChangeListener |
|
*/ |
|
private class AccessibleJComboBoxPropertyChangeListener |
|
implements PropertyChangeListener { |
|
public void propertyChange(PropertyChangeEvent e) { |
|
if (e.getPropertyName() == "editor") { |
|
// set the combo box editor's accessible name |
|
// and description |
|
setEditorNameAndDescription(); |
|
} |
|
} |
|
} |
|
/* |
|
* Sets the combo box editor's accessible name and descripton |
|
*/ |
|
private void setEditorNameAndDescription() { |
|
ComboBoxEditor editor = JComboBox.this.getEditor(); |
|
if (editor != null) { |
|
Component comp = editor.getEditorComponent(); |
|
if (comp instanceof Accessible) { |
|
AccessibleContext ac = comp.getAccessibleContext(); |
|
if (ac != null) { // may be null |
|
ac.setAccessibleName(getAccessibleName()); |
|
ac.setAccessibleDescription(getAccessibleDescription()); |
|
} |
|
} |
|
} |
|
} |
|
/* |
|
* Listener for combo box popup menu |
|
* TIGER - 4669379 4894434 |
|
*/ |
|
private class AccessibleJComboBoxPopupMenuListener |
|
implements PopupMenuListener { |
|
/** |
|
* This method is called before the popup menu becomes visible |
|
*/ |
|
public void popupMenuWillBecomeVisible(PopupMenuEvent e) { |
|
// save the initial selection |
|
if (popupList == null) { |
|
return; |
|
} |
|
int selectedIndex = popupList.getSelectedIndex(); |
|
if (selectedIndex < 0) { |
|
return; |
|
} |
|
previousSelectedAccessible = |
|
popupList.getAccessibleContext().getAccessibleChild(selectedIndex); |
|
} |
|
/** |
|
* This method is called before the popup menu becomes invisible |
|
* Note that a JPopupMenu can become invisible any time |
|
*/ |
|
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { |
|
// ignore |
|
} |
|
/** |
|
* This method is called when the popup menu is canceled |
|
*/ |
|
public void popupMenuCanceled(PopupMenuEvent e) { |
|
// ignore |
|
} |
|
} |
|
/* |
|
* Handles changes to the popup list selection. |
|
* TIGER - 4669379 4894434 4933143 |
|
*/ |
|
private class AccessibleJComboBoxListSelectionListener |
|
implements ListSelectionListener { |
|
public void valueChanged(ListSelectionEvent e) { |
|
if (popupList == null) { |
|
return; |
|
} |
|
// Get the selected popup list item. |
|
int selectedIndex = popupList.getSelectedIndex(); |
|
if (selectedIndex < 0) { |
|
return; |
|
} |
|
Accessible selectedAccessible = |
|
popupList.getAccessibleContext().getAccessibleChild(selectedIndex); |
|
if (selectedAccessible == null) { |
|
return; |
|
} |
|
// Fire a FOCUSED lost PropertyChangeEvent for the |
|
// previously selected list item. |
|
PropertyChangeEvent pce; |
|
if (previousSelectedAccessible != null) { |
|
pce = new PropertyChangeEvent(previousSelectedAccessible, |
|
AccessibleContext.ACCESSIBLE_STATE_PROPERTY, |
|
AccessibleState.FOCUSED, null); |
|
firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY, |
|
null, pce); |
|
} |
|
// Fire a FOCUSED gained PropertyChangeEvent for the |
|
// currently selected list item. |
|
pce = new PropertyChangeEvent(selectedAccessible, |
|
AccessibleContext.ACCESSIBLE_STATE_PROPERTY, |
|
null, AccessibleState.FOCUSED); |
|
firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY, |
|
null, pce); |
|
// Fire the ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY event |
|
// for the combo box. |
|
firePropertyChange(AccessibleContext.ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY, |
|
previousSelectedAccessible, selectedAccessible); |
|
// Save the previous selection. |
|
previousSelectedAccessible = selectedAccessible; |
|
} |
|
} |
|
/** |
|
* Returns the number of accessible children in the object. If all |
|
* of the children of this object implement Accessible, than this |
|
* method should return the number of children of this object. |
|
* |
|
* @return the number of accessible children in the object. |
|
*/ |
|
public int getAccessibleChildrenCount() { |
|
// Always delegate to the UI if it exists |
|
if (ui != null) { |
|
return ui.getAccessibleChildrenCount(JComboBox.this); |
|
} else { |
|
return super.getAccessibleChildrenCount(); |
|
} |
|
} |
|
/** |
|
* Returns the nth Accessible child of the object. |
|
* The child at index zero represents the popup. |
|
* If the combo box is editable, the child at index one |
|
* represents the editor. |
|
* |
|
* @param i zero-based index of child |
|
* @return the nth Accessible child of the object |
|
*/ |
|
public Accessible getAccessibleChild(int i) { |
|
// Always delegate to the UI if it exists |
|
if (ui != null) { |
|
return ui.getAccessibleChild(JComboBox.this, i); |
|
} else { |
|
return super.getAccessibleChild(i); |
|
} |
|
} |
|
/** |
|
* Get the role of this object. |
|
* |
|
* @return an instance of AccessibleRole describing the role of the |
|
* object |
|
* @see AccessibleRole |
|
*/ |
|
public AccessibleRole getAccessibleRole() { |
|
return AccessibleRole.COMBO_BOX; |
|
} |
|
/** |
|
* Gets the state set of this object. The AccessibleStateSet of |
|
* an object is composed of a set of unique AccessibleStates. |
|
* A change in the AccessibleStateSet of an object will cause a |
|
* PropertyChangeEvent to be fired for the ACCESSIBLE_STATE_PROPERTY |
|
* property. |
|
* |
|
* @return an instance of AccessibleStateSet containing the |
|
* current state set of the object |
|
* @see AccessibleStateSet |
|
* @see AccessibleState |
|
* @see #addPropertyChangeListener |
|
* |
|
*/ |
|
public AccessibleStateSet getAccessibleStateSet() { |
|
// TIGER - 4489748 |
|
AccessibleStateSet ass = super.getAccessibleStateSet(); |
|
if (ass == null) { |
|
ass = new AccessibleStateSet(); |
|
} |
|
if (JComboBox.this.isPopupVisible()) { |
|
ass.add(AccessibleState.EXPANDED); |
|
} else { |
|
ass.add(AccessibleState.COLLAPSED); |
|
} |
|
return ass; |
|
} |
|
/** |
|
* Get the AccessibleAction associated with this object. In the |
|
* implementation of the Java Accessibility API for this class, |
|
* return this object, which is responsible for implementing the |
|
* AccessibleAction interface on behalf of itself. |
|
* |
|
* @return this object |
|
*/ |
|
public AccessibleAction getAccessibleAction() { |
|
return this; |
|
} |
|
/** |
|
* Return a description of the specified action of the object. |
|
* |
|
* @param i zero-based index of the actions |
|
*/ |
|
public String getAccessibleActionDescription(int i) { |
|
if (i == 0) { |
|
return UIManager.getString("ComboBox.togglePopupText"); |
|
} |
|
else { |
|
return null; |
|
} |
|
} |
|
/** |
|
* Returns the number of Actions available in this object. The |
|
* default behavior of a combo box is to have one action. |
|
* |
|
* @return 1, the number of Actions in this object |
|
*/ |
|
public int getAccessibleActionCount() { |
|
return 1; |
|
} |
|
/** |
|
* Perform the specified Action on the object |
|
* |
|
* @param i zero-based index of actions |
|
* @return true if the the action was performed; else false. |
|
*/ |
|
public boolean doAccessibleAction(int i) { |
|
if (i == 0) { |
|
setPopupVisible(!isPopupVisible()); |
|
return true; |
|
} |
|
else { |
|
return false; |
|
} |
|
} |
|
/** |
|
* Get the AccessibleSelection associated with this object. In the |
|
* implementation of the Java Accessibility API for this class, |
|
* return this object, which is responsible for implementing the |
|
* AccessibleSelection interface on behalf of itself. |
|
* |
|
* @return this object |
|
*/ |
|
public AccessibleSelection getAccessibleSelection() { |
|
return this; |
|
} |
|
/** |
|
* Returns the number of Accessible children currently selected. |
|
* If no children are selected, the return value will be 0. |
|
* |
|
* @return the number of items currently selected. |
|
* @since 1.3 |
|
*/ |
|
public int getAccessibleSelectionCount() { |
|
Object o = JComboBox.this.getSelectedItem(); |
|
if (o != null) { |
|
return 1; |
|
} else { |
|
return 0; |
|
} |
|
} |
|
/** |
|
* Returns an Accessible representing the specified selected child |
|
* in the popup. If there isn't a selection, or there are |
|
* fewer children selected than the integer passed in, the return |
|
* value will be null. |
|
* <p>Note that the index represents the i-th selected child, which |
|
* is different from the i-th child. |
|
* |
|
* @param i the zero-based index of selected children |
|
* @return the i-th selected child |
|
* @see #getAccessibleSelectionCount |
|
* @since 1.3 |
|
*/ |
|
public Accessible getAccessibleSelection(int i) { |
|
// Get the popup |
|
Accessible a = |
|
JComboBox.this.getUI().getAccessibleChild(JComboBox.this, 0); |
|
if (a != null && |
|
a instanceof javax.swing.plaf.basic.ComboPopup) { |
|
// get the popup list |
|
JList list = ((javax.swing.plaf.basic.ComboPopup)a).getList(); |
|
// return the i-th selection in the popup list |
|
AccessibleContext ac = list.getAccessibleContext(); |
|
if (ac != null) { |
|
AccessibleSelection as = ac.getAccessibleSelection(); |
|
if (as != null) { |
|
return as.getAccessibleSelection(i); |
|
} |
|
} |
|
} |
|
return null; |
|
} |
|
/** |
|
* Determines if the current child of this object is selected. |
|
* |
|
* @return true if the current child of this object is selected; |
|
* else false |
|
* @param i the zero-based index of the child in this Accessible |
|
* object. |
|
* @see AccessibleContext#getAccessibleChild |
|
* @since 1.3 |
|
*/ |
|
public boolean isAccessibleChildSelected(int i) { |
|
return JComboBox.this.getSelectedIndex() == i; |
|
} |
|
/** |
|
* Adds the specified Accessible child of the object to the object's |
|
* selection. If the object supports multiple selections, |
|
* the specified child is added to any existing selection, otherwise |
|
* it replaces any existing selection in the object. If the |
|
* specified child is already selected, this method has no effect. |
|
* |
|
* @param i the zero-based index of the child |
|
* @see AccessibleContext#getAccessibleChild |
|
* @since 1.3 |
|
*/ |
|
public void addAccessibleSelection(int i) { |
|
// TIGER - 4856195 |
|
clearAccessibleSelection(); |
|
JComboBox.this.setSelectedIndex(i); |
|
} |
|
/** |
|
* Removes the specified child of the object from the object's |
|
* selection. If the specified item isn't currently selected, this |
|
* method has no effect. |
|
* |
|
* @param i the zero-based index of the child |
|
* @see AccessibleContext#getAccessibleChild |
|
* @since 1.3 |
|
*/ |
|
public void removeAccessibleSelection(int i) { |
|
if (JComboBox.this.getSelectedIndex() == i) { |
|
clearAccessibleSelection(); |
|
} |
|
} |
|
/** |
|
* Clears the selection in the object, so that no children in the |
|
* object are selected. |
|
* @since 1.3 |
|
*/ |
|
public void clearAccessibleSelection() { |
|
JComboBox.this.setSelectedIndex(-1); |
|
} |
|
/** |
|
* Causes every child of the object to be selected |
|
* if the object supports multiple selections. |
|
* @since 1.3 |
|
*/ |
|
public void selectAllAccessibleSelection() { |
|
// do nothing since multiple selection is not supported |
|
} |
|
// public Accessible getAccessibleAt(Point p) { |
|
// Accessible a = getAccessibleChild(1); |
|
// if ( a != null ) { |
|
// return a; // the editor |
|
// } |
|
// else { |
|
// return getAccessibleChild(0); // the list |
|
// } |
|
// } |
|
private EditorAccessibleContext editorAccessibleContext = null; |
|
private class AccessibleEditor implements Accessible { |
|
public AccessibleContext getAccessibleContext() { |
|
if (editorAccessibleContext == null) { |
|
Component c = JComboBox.this.getEditor().getEditorComponent(); |
|
if (c instanceof Accessible) { |
|
editorAccessibleContext = |
|
new EditorAccessibleContext((Accessible)c); |
|
} |
|
} |
|
return editorAccessibleContext; |
|
} |
|
} |
|
/* |
|
* Wrapper class for the AccessibleContext implemented by the |
|
* combo box editor. Delegates all method calls except |
|
* getAccessibleIndexInParent to the editor. The |
|
* getAccessibleIndexInParent method returns the selected |
|
* index in the combo box. |
|
*/ |
|
private class EditorAccessibleContext extends AccessibleContext { |
|
private AccessibleContext ac; |
|
private EditorAccessibleContext() { |
|
} |
|
/* |
|
* @param a the AccessibleContext implemented by the |
|
* combo box editor |
|
*/ |
|
EditorAccessibleContext(Accessible a) { |
|
this.ac = a.getAccessibleContext(); |
|
} |
|
/** |
|
* Gets the accessibleName property of this object. The accessibleName |
|
* property of an object is a localized String that designates the purpose |
|
* of the object. For example, the accessibleName property of a label |
|
* or button might be the text of the label or button itself. In the |
|
* case of an object that doesn't display its name, the accessibleName |
|
* should still be set. For example, in the case of a text field used |
|
* to enter the name of a city, the accessibleName for the en_US locale |
|
* could be 'city.' |
|
* |
|
* @return the localized name of the object; null if this |
|
* object does not have a name |
|
* |
|
* @see #setAccessibleName |
|
*/ |
|
public String getAccessibleName() { |
|
return ac.getAccessibleName(); |
|
} |
|
/** |
|
* Sets the localized accessible name of this object. Changing the |
|
* name will cause a PropertyChangeEvent to be fired for the |
|
* ACCESSIBLE_NAME_PROPERTY property. |
|
* |
|
* @param s the new localized name of the object. |
|
* |
|
* @see #getAccessibleName |
|
* @see #addPropertyChangeListener |
|
* |
|
* @beaninfo |
|
* preferred: true |
|
* description: Sets the accessible name for the component. |
|
*/ |
|
public void setAccessibleName(String s) { |
|
ac.setAccessibleName(s); |
|
} |
|
/** |
|
* Gets the accessibleDescription property of this object. The |
|
* accessibleDescription property of this object is a short localized |
|
* phrase describing the purpose of the object. For example, in the |
|
* case of a 'Cancel' button, the accessibleDescription could be |
|
* 'Ignore changes and close dialog box.' |
|
* |
|
* @return the localized description of the object; null if |
|
* this object does not have a description |
|
* |
|
* @see #setAccessibleDescription |
|
*/ |
|
public String getAccessibleDescription() { |
|
return ac.getAccessibleDescription(); |
|
} |
|
/** |
|
* Sets the accessible description of this object. Changing the |
|
* name will cause a PropertyChangeEvent to be fired for the |
|
* ACCESSIBLE_DESCRIPTION_PROPERTY property. |
|
* |
|
* @param s the new localized description of the object |
|
* |
|
* @see #setAccessibleName |
|
* @see #addPropertyChangeListener |
|
* |
|
* @beaninfo |
|
* preferred: true |
|
* description: Sets the accessible description for the component. |
|
*/ |
|
public void setAccessibleDescription(String s) { |
|
ac.setAccessibleDescription(s); |
|
} |
|
/** |
|
* Gets the role of this object. The role of the object is the generic |
|
* purpose or use of the class of this object. For example, the role |
|
* of a push button is AccessibleRole.PUSH_BUTTON. The roles in |
|
* AccessibleRole are provided so component developers can pick from |
|
* a set of predefined roles. This enables assistive technologies to |
|
* provide a consistent interface to various tweaked subclasses of |
|
* components (e.g., use AccessibleRole.PUSH_BUTTON for all components |
|
* that act like a push button) as well as distinguish between subclasses |
|
* that behave differently (e.g., AccessibleRole.CHECK_BOX for check boxes |
|
* and AccessibleRole.RADIO_BUTTON for radio buttons). |
|
* <p>Note that the AccessibleRole class is also extensible, so |
|
* custom component developers can define their own AccessibleRole's |
|
* if the set of predefined roles is inadequate. |
|
* |
|
* @return an instance of AccessibleRole describing the role of the object |
|
* @see AccessibleRole |
|
*/ |
|
public AccessibleRole getAccessibleRole() { |
|
return ac.getAccessibleRole(); |
|
} |
|
/** |
|
* Gets the state set of this object. The AccessibleStateSet of an object |
|
* is composed of a set of unique AccessibleStates. A change in the |
|
* AccessibleStateSet of an object will cause a PropertyChangeEvent to |
|
* be fired for the ACCESSIBLE_STATE_PROPERTY property. |
|
* |
|
* @return an instance of AccessibleStateSet containing the |
|
* current state set of the object |
|
* @see AccessibleStateSet |
|
* @see AccessibleState |
|
* @see #addPropertyChangeListener |
|
*/ |
|
public AccessibleStateSet getAccessibleStateSet() { |
|
return ac.getAccessibleStateSet(); |
|
} |
|
/** |
|
* Gets the Accessible parent of this object. |
|
* |
|
* @return the Accessible parent of this object; null if this |
|
* object does not have an Accessible parent |
|
*/ |
|
public Accessible getAccessibleParent() { |
|
return ac.getAccessibleParent(); |
|
} |
|
/** |
|
* Sets the Accessible parent of this object. This is meant to be used |
|
* only in the situations where the actual component's parent should |
|
* not be treated as the component's accessible parent and is a method |
|
* that should only be called by the parent of the accessible child. |
|
* |
|
* @param a - Accessible to be set as the parent |
|
*/ |
|
public void setAccessibleParent(Accessible a) { |
|
ac.setAccessibleParent(a); |
|
} |
|
/** |
|
* Gets the 0-based index of this object in its accessible parent. |
|
* |
|
* @return the 0-based index of this object in its parent; -1 if this |
|
* object does not have an accessible parent. |
|
* |
|
* @see #getAccessibleParent |
|
* @see #getAccessibleChildrenCount |
|
* @see #getAccessibleChild |
|
*/ |
|
public int getAccessibleIndexInParent() { |
|
return JComboBox.this.getSelectedIndex(); |
|
} |
|
/** |
|
* Returns the number of accessible children of the object. |
|
* |
|
* @return the number of accessible children of the object. |
|
*/ |
|
public int getAccessibleChildrenCount() { |
|
return ac.getAccessibleChildrenCount(); |
|
} |
|
/** |
|
* Returns the specified Accessible child of the object. The Accessible |
|
* children of an Accessible object are zero-based, so the first child |
|
* of an Accessible child is at index 0, the second child is at index 1, |
|
* and so on. |
|
* |
|
* @param i zero-based index of child |
|
* @return the Accessible child of the object |
|
* @see #getAccessibleChildrenCount |
|
*/ |
|
public Accessible getAccessibleChild(int i) { |
|
return ac.getAccessibleChild(i); |
|
} |
|
/** |
|
* Gets the locale of the component. If the component does not have a |
|
* locale, then the locale of its parent is returned. |
|
* |
|
* @return this component's locale. If this component does not have |
|
* a locale, the locale of its parent is returned. |
|
* |
|
* @exception IllegalComponentStateException |
|
* If the Component does not have its own locale and has not yet been |
|
* added to a containment hierarchy such that the locale can be |
|
* determined from the containing parent. |
|
*/ |
|
public Locale getLocale() throws IllegalComponentStateException { |
|
return ac.getLocale(); |
|
} |
|
/** |
|
* Adds a PropertyChangeListener to the listener list. |
|
* The listener is registered for all Accessible properties and will |
|
* be called when those properties change. |
|
* |
|
* @see #ACCESSIBLE_NAME_PROPERTY |
|
* @see #ACCESSIBLE_DESCRIPTION_PROPERTY |
|
* @see #ACCESSIBLE_STATE_PROPERTY |
|
* @see #ACCESSIBLE_VALUE_PROPERTY |
|
* @see #ACCESSIBLE_SELECTION_PROPERTY |
|
* @see #ACCESSIBLE_TEXT_PROPERTY |
|
* @see #ACCESSIBLE_VISIBLE_DATA_PROPERTY |
|
* |
|
* @param listener The PropertyChangeListener to be added |
|
*/ |
|
public void addPropertyChangeListener(PropertyChangeListener listener) { |
|
ac.addPropertyChangeListener(listener); |
|
} |
|
/** |
|
* Removes a PropertyChangeListener from the listener list. |
|
* This removes a PropertyChangeListener that was registered |
|
* for all properties. |
|
* |
|
* @param listener The PropertyChangeListener to be removed |
|
*/ |
|
public void removePropertyChangeListener(PropertyChangeListener listener) { |
|
ac.removePropertyChangeListener(listener); |
|
} |
|
/** |
|
* Gets the AccessibleAction associated with this object that supports |
|
* one or more actions. |
|
* |
|
* @return AccessibleAction if supported by object; else return null |
|
* @see AccessibleAction |
|
*/ |
|
public AccessibleAction getAccessibleAction() { |
|
return ac.getAccessibleAction(); |
|
} |
|
/** |
|
* Gets the AccessibleComponent associated with this object that has a |
|
* graphical representation. |
|
* |
|
* @return AccessibleComponent if supported by object; else return null |
|
* @see AccessibleComponent |
|
*/ |
|
public AccessibleComponent getAccessibleComponent() { |
|
return ac.getAccessibleComponent(); |
|
} |
|
/** |
|
* Gets the AccessibleSelection associated with this object which allows its |
|
* Accessible children to be selected. |
|
* |
|
* @return AccessibleSelection if supported by object; else return null |
|
* @see AccessibleSelection |
|
*/ |
|
public AccessibleSelection getAccessibleSelection() { |
|
return ac.getAccessibleSelection(); |
|
} |
|
/** |
|
* Gets the AccessibleText associated with this object presenting |
|
* text on the display. |
|
* |
|
* @return AccessibleText if supported by object; else return null |
|
* @see AccessibleText |
|
*/ |
|
public AccessibleText getAccessibleText() { |
|
return ac.getAccessibleText(); |
|
} |
|
/** |
|
* Gets the AccessibleEditableText associated with this object |
|
* presenting editable text on the display. |
|
* |
|
* @return AccessibleEditableText if supported by object; else return null |
|
* @see AccessibleEditableText |
|
*/ |
|
public AccessibleEditableText getAccessibleEditableText() { |
|
return ac.getAccessibleEditableText(); |
|
} |
|
/** |
|
* Gets the AccessibleValue associated with this object that supports a |
|
* Numerical value. |
|
* |
|
* @return AccessibleValue if supported by object; else return null |
|
* @see AccessibleValue |
|
*/ |
|
public AccessibleValue getAccessibleValue() { |
|
return ac.getAccessibleValue(); |
|
} |
|
/** |
|
* Gets the AccessibleIcons associated with an object that has |
|
* one or more associated icons |
|
* |
|
* @return an array of AccessibleIcon if supported by object; |
|
* otherwise return null |
|
* @see AccessibleIcon |
|
*/ |
|
public AccessibleIcon [] getAccessibleIcon() { |
|
return ac.getAccessibleIcon(); |
|
} |
|
/** |
|
* Gets the AccessibleRelationSet associated with an object |
|
* |
|
* @return an AccessibleRelationSet if supported by object; |
|
* otherwise return null |
|
* @see AccessibleRelationSet |
|
*/ |
|
public AccessibleRelationSet getAccessibleRelationSet() { |
|
return ac.getAccessibleRelationSet(); |
|
} |
|
/** |
|
* Gets the AccessibleTable associated with an object |
|
* |
|
* @return an AccessibleTable if supported by object; |
|
* otherwise return null |
|
* @see AccessibleTable |
|
*/ |
|
public AccessibleTable getAccessibleTable() { |
|
return ac.getAccessibleTable(); |
|
} |
|
/** |
|
* Support for reporting bound property changes. If oldValue and |
|
* newValue are not equal and the PropertyChangeEvent listener list |
|
* is not empty, then fire a PropertyChange event to each listener. |
|
* In general, this is for use by the Accessible objects themselves |
|
* and should not be called by an application program. |
|
* @param propertyName The programmatic name of the property that |
|
* was changed. |
|
* @param oldValue The old value of the property. |
|
* @param newValue The new value of the property. |
|
* @see java.beans.PropertyChangeSupport |
|
* @see #addPropertyChangeListener |
|
* @see #removePropertyChangeListener |
|
* @see #ACCESSIBLE_NAME_PROPERTY |
|
* @see #ACCESSIBLE_DESCRIPTION_PROPERTY |
|
* @see #ACCESSIBLE_STATE_PROPERTY |
|
* @see #ACCESSIBLE_VALUE_PROPERTY |
|
* @see #ACCESSIBLE_SELECTION_PROPERTY |
|
* @see #ACCESSIBLE_TEXT_PROPERTY |
|
* @see #ACCESSIBLE_VISIBLE_DATA_PROPERTY |
|
*/ |
|
public void firePropertyChange(String propertyName, |
|
Object oldValue, |
|
Object newValue) { |
|
ac.firePropertyChange(propertyName, oldValue, newValue); |
|
} |
|
} |
|
} // innerclass AccessibleJComboBox |
|
} |