2412 lines · 86.9 KB · Java
RawDownload
/* * Copyright (c) 1997, 2008, 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<sup><font size="-2">TM</font></sup> * has been added to the <code>java.beans</code> package. * Please see {@link java.beans.XMLEncoder}. * * <p> * See <a href="http://java.sun.com/docs/books/tutorial/uiswing/components/combobox.html">How to Use Combo Boxes</a> * in <a href="http://java.sun.com/Series/Tutorial/index.html"><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 JComponentimplements 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://java.sun.com/products/jfc/tsc/articles/mixing/index.html">Mixing Heavy and Light Components</a>     * on <a href="http://java.sun.com/products/jfc/tsc">     * <em>The Swing Connection</em></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; 

Lines 1–500 of 2412.