Source Code Cross Referenced for JComboBox.java in  » 6.0-JDK-Core » swing » javax » swing » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
Java Source Code / Java Documentation
1.6.0 JDK Core
2.6.0 JDK Modules
3.6.0 JDK Modules com.sun
4.6.0 JDK Modules com.sun.java
5.6.0 JDK Modules sun
6.6.0 JDK Platform
7.Ajax
8.Apache Harmony Java SE
9.Aspect oriented
10.Authentication Authorization
11.Blogger System
12.Build
13.Byte Code
14.Cache
15.Chart
16.Chat
17.Code Analyzer
18.Collaboration
19.Content Management System
20.Database Client
21.Database DBMS
22.Database JDBC Connection Pool
23.Database ORM
24.Development
25.EJB Server
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » swing » javax.swing 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001        /*
0002         * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
0003         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004         *
0005         * This code is free software; you can redistribute it and/or modify it
0006         * under the terms of the GNU General Public License version 2 only, as
0007         * published by the Free Software Foundation.  Sun designates this
0008         * particular file as subject to the "Classpath" exception as provided
0009         * by Sun in the LICENSE file that accompanied this code.
0010         *
0011         * This code is distributed in the hope that it will be useful, but WITHOUT
0012         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
0014         * version 2 for more details (a copy is included in the LICENSE file that
0015         * accompanied this code).
0016         *
0017         * You should have received a copy of the GNU General Public License version
0018         * 2 along with this work; if not, write to the Free Software Foundation,
0019         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020         *
0021         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022         * CA 95054 USA or visit www.sun.com if you need additional information or
0023         * have any questions.
0024         */
0025        package javax.swing;
0026
0027        import java.beans.*;
0028        import java.util.*;
0029
0030        import java.awt.*;
0031        import java.awt.event.*;
0032
0033        import java.io.Serializable;
0034        import java.io.ObjectOutputStream;
0035        import java.io.ObjectInputStream;
0036        import java.io.IOException;
0037
0038        import javax.swing.event.*;
0039        import javax.swing.plaf.*;
0040        import javax.swing.border.*;
0041
0042        import javax.accessibility.*;
0043
0044        /**
0045         * A component that combines a button or editable field and a drop-down list.
0046         * The user can select a value from the drop-down list, which appears at the 
0047         * user's request. If you make the combo box editable, then the combo box
0048         * includes an editable field into which the user can type a value.
0049         * <p>
0050         * <strong>Warning:</strong> Swing is not thread safe. For more
0051         * information see <a
0052         * href="package-summary.html#threading">Swing's Threading
0053         * Policy</a>.
0054         * <p>
0055         * <strong>Warning:</strong>
0056         * Serialized objects of this class will not be compatible with
0057         * future Swing releases. The current serialization support is
0058         * appropriate for short term storage or RMI between applications running
0059         * the same version of Swing.  As of 1.4, support for long term storage
0060         * of all JavaBeans<sup><font size="-2">TM</font></sup>
0061         * has been added to the <code>java.beans</code> package.
0062         * Please see {@link java.beans.XMLEncoder}.
0063         *
0064         * <p>
0065         * See <a href="http://java.sun.com/docs/books/tutorial/uiswing/components/combobox.html">How to Use Combo Boxes</a>
0066         * in <a href="http://java.sun.com/Series/Tutorial/index.html"><em>The Java Tutorial</em></a>
0067         * for further information.
0068         * <p>
0069         * @see ComboBoxModel
0070         * @see DefaultComboBoxModel
0071         *
0072         * @beaninfo
0073         *   attribute: isContainer false
0074         * description: A combination of a text field and a drop-down list.
0075         *
0076         * @version 1.147 05/05/07
0077         * @author Arnaud Weber
0078         * @author Mark Davidson
0079         */
0080        public class JComboBox extends JComponent implements  ItemSelectable,
0081                ListDataListener, ActionListener, Accessible {
0082            /**
0083             * @see #getUIClassID
0084             * @see #readObject
0085             */
0086            private static final String uiClassID = "ComboBoxUI";
0087
0088            /**
0089             * This protected field is implementation specific. Do not access directly
0090             * or override. Use the accessor methods instead.
0091             *
0092             * @see #getModel
0093             * @see #setModel
0094             */
0095            protected ComboBoxModel dataModel;
0096            /**
0097             * This protected field is implementation specific. Do not access directly
0098             * or override. Use the accessor methods instead.
0099             *
0100             * @see #getRenderer
0101             * @see #setRenderer
0102             */
0103            protected ListCellRenderer renderer;
0104            /**
0105             * This protected field is implementation specific. Do not access directly
0106             * or override. Use the accessor methods instead.
0107             *
0108             * @see #getEditor
0109             * @see #setEditor
0110             */
0111            protected ComboBoxEditor editor;
0112            /**
0113             * This protected field is implementation specific. Do not access directly
0114             * or override. Use the accessor methods instead.
0115             *
0116             * @see #getMaximumRowCount
0117             * @see #setMaximumRowCount
0118             */
0119            protected int maximumRowCount = 8;
0120
0121            /**
0122             * This protected field is implementation specific. Do not access directly
0123             * or override. Use the accessor methods instead.
0124             *
0125             * @see #isEditable
0126             * @see #setEditable
0127             */
0128            protected boolean isEditable = false;
0129            /**
0130             * This protected field is implementation specific. Do not access directly
0131             * or override. Use the accessor methods instead.
0132             *
0133             * @see #setKeySelectionManager
0134             * @see #getKeySelectionManager
0135             */
0136            protected KeySelectionManager keySelectionManager = null;
0137            /**
0138             * This protected field is implementation specific. Do not access directly
0139             * or override. Use the accessor methods instead.
0140             *
0141             * @see #setActionCommand
0142             * @see #getActionCommand
0143             */
0144            protected String actionCommand = "comboBoxChanged";
0145            /**
0146             * This protected field is implementation specific. Do not access directly
0147             * or override. Use the accessor methods instead.
0148             *
0149             * @see #setLightWeightPopupEnabled
0150             * @see #isLightWeightPopupEnabled
0151             */
0152            protected boolean lightWeightPopupEnabled = JPopupMenu
0153                    .getDefaultLightWeightPopupEnabled();
0154
0155            /**
0156             * This protected field is implementation specific. Do not access directly
0157             * or override.
0158             */
0159            protected Object selectedItemReminder = null;
0160
0161            private Object prototypeDisplayValue;
0162
0163            // Flag to ensure that infinite loops do not occur with ActionEvents.
0164            private boolean firingActionEvent = false;
0165
0166            // Flag to ensure the we don't get multiple ActionEvents on item selection.
0167            private boolean selectingItem = false;
0168
0169            /**
0170             * Creates a <code>JComboBox</code> that takes its items from an
0171             * existing <code>ComboBoxModel</code>.  Since the
0172             * <code>ComboBoxModel</code> is provided, a combo box created using
0173             * this constructor does not create a default combo box model and
0174             * may impact how the insert, remove and add methods behave.
0175             *
0176             * @param aModel the <code>ComboBoxModel</code> that provides the 
0177             * 		displayed list of items
0178             * @see DefaultComboBoxModel
0179             */
0180            public JComboBox(ComboBoxModel aModel) {
0181                super ();
0182                setModel(aModel);
0183                init();
0184            }
0185
0186            /** 
0187             * Creates a <code>JComboBox</code> that contains the elements
0188             * in the specified array.  By default the first item in the array
0189             * (and therefore the data model) becomes selected.
0190             *
0191             * @param items  an array of objects to insert into the combo box
0192             * @see DefaultComboBoxModel
0193             */
0194            public JComboBox(final Object items[]) {
0195                super ();
0196                setModel(new DefaultComboBoxModel(items));
0197                init();
0198            }
0199
0200            /**
0201             * Creates a <code>JComboBox</code> that contains the elements
0202             * in the specified Vector.  By default the first item in the vector
0203             * (and therefore the data model) becomes selected.
0204             *
0205             * @param items  an array of vectors to insert into the combo box
0206             * @see DefaultComboBoxModel
0207             */
0208            public JComboBox(Vector<?> items) {
0209                super ();
0210                setModel(new DefaultComboBoxModel(items));
0211                init();
0212            }
0213
0214            /**
0215             * Creates a <code>JComboBox</code> with a default data model.
0216             * The default data model is an empty list of objects.
0217             * Use <code>addItem</code> to add items.  By default the first item
0218             * in the data model becomes selected.
0219             *
0220             * @see DefaultComboBoxModel
0221             */
0222            public JComboBox() {
0223                super ();
0224                setModel(new DefaultComboBoxModel());
0225                init();
0226            }
0227
0228            private void init() {
0229                installAncestorListener();
0230                setOpaque(true);
0231                updateUI();
0232            }
0233
0234            protected void installAncestorListener() {
0235                addAncestorListener(new AncestorListener() {
0236                    public void ancestorAdded(AncestorEvent event) {
0237                        hidePopup();
0238                    }
0239
0240                    public void ancestorRemoved(AncestorEvent event) {
0241                        hidePopup();
0242                    }
0243
0244                    public void ancestorMoved(AncestorEvent event) {
0245                        if (event.getSource() != JComboBox.this )
0246                            hidePopup();
0247                    }
0248                });
0249            }
0250
0251            /**
0252             * Sets the L&F object that renders this component.
0253             *
0254             * @param ui  the <code>ComboBoxUI</code> L&F object
0255             * @see UIDefaults#getUI
0256             *
0257             * @beaninfo
0258             *        bound: true
0259             *       hidden: true
0260             *    attribute: visualUpdate true
0261             *  description: The UI object that implements the Component's LookAndFeel. 
0262             */
0263            public void setUI(ComboBoxUI ui) {
0264                super .setUI(ui);
0265            }
0266
0267            /**
0268             * Resets the UI property to a value from the current look and feel.
0269             *
0270             * @see JComponent#updateUI
0271             */
0272            public void updateUI() {
0273                setUI((ComboBoxUI) UIManager.getUI(this ));
0274
0275                ListCellRenderer renderer = getRenderer();
0276                if (renderer instanceof  Component) {
0277                    SwingUtilities.updateComponentTreeUI((Component) renderer);
0278                }
0279            }
0280
0281            /**
0282             * Returns the name of the L&F class that renders this component.
0283             *
0284             * @return the string "ComboBoxUI"
0285             * @see JComponent#getUIClassID
0286             * @see UIDefaults#getUI
0287             */
0288            public String getUIClassID() {
0289                return uiClassID;
0290            }
0291
0292            /**
0293             * Returns the L&F object that renders this component.
0294             *
0295             * @return the ComboBoxUI object that renders this component
0296             */
0297            public ComboBoxUI getUI() {
0298                return (ComboBoxUI) ui;
0299            }
0300
0301            /**
0302             * Sets the data model that the <code>JComboBox</code> uses to obtain
0303             * the list of items.
0304             *
0305             * @param aModel the <code>ComboBoxModel</code> that provides the
0306             *	displayed list of items
0307             * 
0308             * @beaninfo
0309             *        bound: true
0310             *  description: Model that the combo box uses to get data to display.
0311             */
0312            public void setModel(ComboBoxModel aModel) {
0313                ComboBoxModel oldModel = dataModel;
0314                if (oldModel != null) {
0315                    oldModel.removeListDataListener(this );
0316                }
0317                dataModel = aModel;
0318                dataModel.addListDataListener(this );
0319
0320                // set the current selected item.
0321                selectedItemReminder = dataModel.getSelectedItem();
0322
0323                firePropertyChange("model", oldModel, dataModel);
0324            }
0325
0326            /**
0327             * Returns the data model currently used by the <code>JComboBox</code>.
0328             *
0329             * @return the <code>ComboBoxModel</code> that provides the displayed
0330             * 			list of items
0331             */
0332            public ComboBoxModel getModel() {
0333                return dataModel;
0334            }
0335
0336            /*
0337             * Properties
0338             */
0339
0340            /**
0341             * Sets the <code>lightWeightPopupEnabled</code> property, which
0342             * provides a hint as to whether or not a lightweight
0343             * <code>Component</code> should be used to contain the
0344             * <code>JComboBox</code>, versus a heavyweight 
0345             * <code>Component</code> such as a <code>Panel</code>
0346             * or a <code>Window</code>.  The decision of lightweight
0347             * versus heavyweight is ultimately up to the 
0348             * <code>JComboBox</code>.  Lightweight windows are more
0349             * efficient than heavyweight windows, but lightweight
0350             * and heavyweight components do not mix well in a GUI.
0351             * If your application mixes lightweight and heavyweight 
0352             * components, you should disable lightweight popups.
0353             * The default value for the <code>lightWeightPopupEnabled</code>
0354             * property is <code>true</code>, unless otherwise specified
0355             * by the look and feel.  Some look and feels always use
0356             * heavyweight popups, no matter what the value of this property.
0357             * <p>
0358             * See the article <a href="http://java.sun.com/products/jfc/tsc/articles/mixing/index.html">Mixing Heavy and Light Components</a> 
0359             * on <a href="http://java.sun.com/products/jfc/tsc">
0360             * <em>The Swing Connection</em></a>
0361             * This method fires a property changed event.
0362             *
0363             * @param aFlag if <code>true</code>, lightweight popups are desired
0364             *
0365             * @beaninfo
0366             *        bound: true
0367             *       expert: true
0368             *  description: Set to <code>false</code> to require heavyweight popups.
0369             */
0370            public void setLightWeightPopupEnabled(boolean aFlag) {
0371                boolean oldFlag = lightWeightPopupEnabled;
0372                lightWeightPopupEnabled = aFlag;
0373                firePropertyChange("lightWeightPopupEnabled", oldFlag,
0374                        lightWeightPopupEnabled);
0375            }
0376
0377            /**
0378             * Gets the value of the <code>lightWeightPopupEnabled</code>
0379             * property.
0380             *
0381             * @return the value of the <code>lightWeightPopupEnabled</code>
0382             *    property
0383             * @see #setLightWeightPopupEnabled
0384             */
0385            public boolean isLightWeightPopupEnabled() {
0386                return lightWeightPopupEnabled;
0387            }
0388
0389            /**
0390             * Determines whether the <code>JComboBox</code> field is editable.
0391             * An editable <code>JComboBox</code> allows the user to type into the
0392             * field or selected an item from the list to initialize the field,
0393             * after which it can be edited. (The editing affects only the field,
0394             * the list item remains intact.) A non editable <code>JComboBox</code> 
0395             * displays the selected item in the field,
0396             * but the selection cannot be modified.
0397             *
0398             * @param aFlag a boolean value, where true indicates that the
0399             *			field is editable
0400             * 
0401             * @beaninfo
0402             *        bound: true
0403             *    preferred: true
0404             *  description: If true, the user can type a new value in the combo box.
0405             */
0406            public void setEditable(boolean aFlag) {
0407                boolean oldFlag = isEditable;
0408                isEditable = aFlag;
0409                firePropertyChange("editable", oldFlag, isEditable);
0410            }
0411
0412            /**
0413             * Returns true if the <code>JComboBox</code> is editable.
0414             * By default, a combo box is not editable.
0415             * 
0416             * @return true if the <code>JComboBox</code> is editable, else false
0417             */
0418            public boolean isEditable() {
0419                return isEditable;
0420            }
0421
0422            /**
0423             * Sets the maximum number of rows the <code>JComboBox</code> displays.
0424             * If the number of objects in the model is greater than count,
0425             * the combo box uses a scrollbar.
0426             *
0427             * @param count an integer specifying the maximum number of items to
0428             *              display in the list before using a scrollbar
0429             * @beaninfo
0430             *        bound: true
0431             *    preferred: true
0432             *  description: The maximum number of rows the popup should have
0433             */
0434            public void setMaximumRowCount(int count) {
0435                int oldCount = maximumRowCount;
0436                maximumRowCount = count;
0437                firePropertyChange("maximumRowCount", oldCount, maximumRowCount);
0438            }
0439
0440            /**
0441             * Returns the maximum number of items the combo box can display 
0442             * without a scrollbar
0443             *
0444             * @return an integer specifying the maximum number of items that are 
0445             *         displayed in the list before using a scrollbar
0446             */
0447            public int getMaximumRowCount() {
0448                return maximumRowCount;
0449            }
0450
0451            /**
0452             * Sets the renderer that paints the list items and the item selected from the list in
0453             * the JComboBox field. The renderer is used if the JComboBox is not
0454             * editable. If it is editable, the editor is used to render and edit
0455             * the selected item.
0456             * <p>
0457             * The default renderer displays a string or an icon.
0458             * Other renderers can handle graphic images and composite items.
0459             * <p>
0460             * To display the selected item,
0461             * <code>aRenderer.getListCellRendererComponent</code>
0462             * is called, passing the list object and an index of -1.
0463             *  
0464             * @param aRenderer  the <code>ListCellRenderer</code> that
0465             *			displays the selected item
0466             * @see #setEditor
0467             * @beaninfo
0468             *      bound: true
0469             *     expert: true
0470             *  description: The renderer that paints the item selected in the list.
0471             */
0472            public void setRenderer(ListCellRenderer aRenderer) {
0473                ListCellRenderer oldRenderer = renderer;
0474                renderer = aRenderer;
0475                firePropertyChange("renderer", oldRenderer, renderer);
0476                invalidate();
0477            }
0478
0479            /**
0480             * Returns the renderer used to display the selected item in the 
0481             * <code>JComboBox</code> field.
0482             *  
0483             * @return  the <code>ListCellRenderer</code> that displays
0484             *			the selected item.
0485             */
0486            public ListCellRenderer getRenderer() {
0487                return renderer;
0488            }
0489
0490            /**
0491             * Sets the editor used to paint and edit the selected item in the 
0492             * <code>JComboBox</code> field.  The editor is used only if the
0493             * receiving <code>JComboBox</code> is editable. If not editable,
0494             * the combo box uses the renderer to paint the selected item.
0495             *  
0496             * @param anEditor  the <code>ComboBoxEditor</code> that
0497             *			displays the selected item
0498             * @see #setRenderer
0499             * @beaninfo
0500             *     bound: true
0501             *    expert: true
0502             *  description: The editor that combo box uses to edit the current value
0503             */
0504            public void setEditor(ComboBoxEditor anEditor) {
0505                ComboBoxEditor oldEditor = editor;
0506
0507                if (editor != null) {
0508                    editor.removeActionListener(this );
0509                }
0510                editor = anEditor;
0511                if (editor != null) {
0512                    editor.addActionListener(this );
0513                }
0514                firePropertyChange("editor", oldEditor, editor);
0515            }
0516
0517            /**
0518             * Returns the editor used to paint and edit the selected item in the 
0519             * <code>JComboBox</code> field.
0520             *  
0521             * @return the <code>ComboBoxEditor</code> that displays the selected item
0522             */
0523            public ComboBoxEditor getEditor() {
0524                return editor;
0525            }
0526
0527            // 
0528            // Selection
0529            // 
0530
0531            /** 
0532             * Sets the selected item in the combo box display area to the object in 
0533             * the argument.
0534             * If <code>anObject</code> is in the list, the display area shows 
0535             * <code>anObject</code> selected.
0536             * <p>
0537             * If <code>anObject</code> is <i>not</i> in the list and the combo box is
0538             * uneditable, it will not change the current selection. For editable 
0539             * combo boxes, the selection will change to <code>anObject</code>.
0540             * <p>
0541             * If this constitutes a change in the selected item, 
0542             * <code>ItemListener</code>s added to the combo box will be notified with
0543             * one or two <code>ItemEvent</code>s.
0544             * If there is a current selected item, an <code>ItemEvent</code> will be
0545             * fired and the state change will be <code>ItemEvent.DESELECTED</code>. 
0546             * If <code>anObject</code> is in the list and is not currently selected
0547             * then an <code>ItemEvent</code> will be fired and the state change will 
0548             * be <code>ItemEvent.SELECTED</code>.
0549             * <p>
0550             * <code>ActionListener</code>s added to the combo box will be notified
0551             * with an <code>ActionEvent</code> when this method is called.
0552             *
0553             * @param anObject  the list object to select; use <code>null</code> to
0554                                clear the selection
0555             * @beaninfo
0556             *    preferred:   true
0557             *    description: Sets the selected item in the JComboBox.
0558             */
0559            public void setSelectedItem(Object anObject) {
0560                Object oldSelection = selectedItemReminder;
0561                Object objectToSelect = anObject;
0562                if (oldSelection == null || !oldSelection.equals(anObject)) {
0563
0564                    if (anObject != null && !isEditable()) {
0565                        // For non editable combo boxes, an invalid selection
0566                        // will be rejected.
0567                        boolean found = false;
0568                        for (int i = 0; i < dataModel.getSize(); i++) {
0569                            Object element = dataModel.getElementAt(i);
0570                            if (anObject.equals(element)) {
0571                                found = true;
0572                                objectToSelect = element;
0573                                break;
0574                            }
0575                        }
0576                        if (!found) {
0577                            return;
0578                        }
0579                    }
0580
0581                    // Must toggle the state of this flag since this method
0582                    // call may result in ListDataEvents being fired.
0583                    selectingItem = true;
0584                    dataModel.setSelectedItem(objectToSelect);
0585                    selectingItem = false;
0586
0587                    if (selectedItemReminder != dataModel.getSelectedItem()) {
0588                        // in case a users implementation of ComboBoxModel
0589                        // doesn't fire a ListDataEvent when the selection
0590                        // changes.
0591                        selectedItemChanged();
0592                    }
0593                }
0594                fireActionEvent();
0595            }
0596
0597            /**
0598             * Returns the current selected item.
0599             * <p>
0600             * If the combo box is editable, then this value may not have been added
0601             * to the combo box with <code>addItem</code>, <code>insertItemAt</code> 
0602             * or the data constructors.
0603             * 
0604             * @return the current selected Object
0605             * @see #setSelectedItem
0606             */
0607            public Object getSelectedItem() {
0608                return dataModel.getSelectedItem();
0609            }
0610
0611            /**
0612             * Selects the item at index <code>anIndex</code>.
0613             *
0614             * @param anIndex an integer specifying the list item to select,
0615             *			where 0 specifies the first item in the list and -1 indicates no selection
0616             * @exception IllegalArgumentException if <code>anIndex</code> < -1 or
0617             *			<code>anIndex</code> is greater than or equal to size
0618             * @beaninfo
0619             *   preferred: true
0620             *  description: The item at index is selected.
0621             */
0622            public void setSelectedIndex(int anIndex) {
0623                int size = dataModel.getSize();
0624
0625                if (anIndex == -1) {
0626                    setSelectedItem(null);
0627                } else if (anIndex < -1 || anIndex >= size) {
0628                    throw new IllegalArgumentException("setSelectedIndex: "
0629                            + anIndex + " out of bounds");
0630                } else {
0631                    setSelectedItem(dataModel.getElementAt(anIndex));
0632                }
0633            }
0634
0635            /**
0636             * Returns the first item in the list that matches the given item.
0637             * The result is not always defined if the <code>JComboBox</code>
0638             * allows selected items that are not in the list. 
0639             * Returns -1 if there is no selected item or if the user specified
0640             * an item which is not in the list.
0641             
0642             * @return an integer specifying the currently selected list item,
0643             *			where 0 specifies
0644             *                	the first item in the list;
0645             *			or -1 if no item is selected or if
0646             *                	the currently selected item is not in the list
0647             */
0648            public int getSelectedIndex() {
0649                Object sObject = dataModel.getSelectedItem();
0650                int i, c;
0651                Object obj;
0652
0653                for (i = 0, c = dataModel.getSize(); i < c; i++) {
0654                    obj = dataModel.getElementAt(i);
0655                    if (obj != null && obj.equals(sObject))
0656                        return i;
0657                }
0658                return -1;
0659            }
0660
0661            /**
0662             * Returns the "prototypical display" value - an Object used
0663             * for the calculation of the display height and width.
0664             *
0665             * @return the value of the <code>prototypeDisplayValue</code> property
0666             * @see #setPrototypeDisplayValue
0667             * @since 1.4
0668             */
0669            public Object getPrototypeDisplayValue() {
0670                return prototypeDisplayValue;
0671            }
0672
0673            /**
0674             * Sets the prototype display value used to calculate the size of the display 
0675             * for the UI portion. 
0676             * <p>
0677             * If a prototype display value is specified, the preferred size of
0678             * the combo box is calculated by configuring the renderer with the
0679             * prototype display value and obtaining its preferred size. Specifying
0680             * the preferred display value is often useful when the combo box will be
0681             * displaying large amounts of data. If no prototype display value has
0682             * been specified, the renderer must be configured for each value from
0683             * the model and its preferred size obtained, which can be
0684             * relatively expensive.
0685             * 
0686             * @param prototypeDisplayValue 
0687             * @see #getPrototypeDisplayValue
0688             * @since 1.4
0689             * @beaninfo
0690             *       bound: true
0691             *   attribute: visualUpdate true
0692             * description: The display prototype value, used to compute display width and height.
0693             */
0694            public void setPrototypeDisplayValue(Object prototypeDisplayValue) {
0695                Object oldValue = this .prototypeDisplayValue;
0696                this .prototypeDisplayValue = prototypeDisplayValue;
0697                firePropertyChange("prototypeDisplayValue", oldValue,
0698                        prototypeDisplayValue);
0699            }
0700
0701            /** 
0702             * Adds an item to the item list.
0703             * This method works only if the <code>JComboBox</code> uses a
0704             * mutable data model.
0705             * <p>
0706             * <strong>Warning:</strong>
0707             * Focus and keyboard navigation problems may arise if you add duplicate 
0708             * String objects. A workaround is to add new objects instead of String 
0709             * objects and make sure that the toString() method is defined. 
0710             * For example:
0711             * <pre>
0712             *   comboBox.addItem(makeObj("Item 1"));
0713             *   comboBox.addItem(makeObj("Item 1"));
0714             *   ...
0715             *   private Object makeObj(final String item)  {
0716             *     return new Object() { public String toString() { return item; } };
0717             *   }
0718             * </pre>
0719             *
0720             * @param anObject the Object to add to the list
0721             * @see MutableComboBoxModel
0722             */
0723            public void addItem(Object anObject) {
0724                checkMutableComboBoxModel();
0725                ((MutableComboBoxModel) dataModel).addElement(anObject);
0726            }
0727
0728            /** 
0729             * Inserts an item into the item list at a given index. 
0730             * This method works only if the <code>JComboBox</code> uses a
0731             * mutable data model.
0732             *
0733             * @param anObject the <code>Object</code> to add to the list
0734             * @param index    an integer specifying the position at which
0735             *			to add the item
0736             * @see MutableComboBoxModel
0737             */
0738            public void insertItemAt(Object anObject, int index) {
0739                checkMutableComboBoxModel();
0740                ((MutableComboBoxModel) dataModel).insertElementAt(anObject,
0741                        index);
0742            }
0743
0744            /** 
0745             * Removes an item from the item list.
0746             * This method works only if the <code>JComboBox</code> uses a
0747             * mutable data model.
0748             *
0749             * @param anObject  the object to remove from the item list
0750             * @see MutableComboBoxModel
0751             */
0752            public void removeItem(Object anObject) {
0753                checkMutableComboBoxModel();
0754                ((MutableComboBoxModel) dataModel).removeElement(anObject);
0755            }
0756
0757            /**  
0758             * Removes the item at <code>anIndex</code>
0759             * This method works only if the <code>JComboBox</code> uses a
0760             * mutable data model.
0761             *
0762             * @param anIndex  an int specifying the index of the item to remove,
0763             *			where 0
0764             *                 	indicates the first item in the list
0765             * @see MutableComboBoxModel
0766             */
0767            public void removeItemAt(int anIndex) {
0768                checkMutableComboBoxModel();
0769                ((MutableComboBoxModel) dataModel).removeElementAt(anIndex);
0770            }
0771
0772            /** 
0773             * Removes all items from the item list.
0774             */
0775            public void removeAllItems() {
0776                checkMutableComboBoxModel();
0777                MutableComboBoxModel model = (MutableComboBoxModel) dataModel;
0778                int size = model.getSize();
0779
0780                if (model instanceof  DefaultComboBoxModel) {
0781                    ((DefaultComboBoxModel) model).removeAllElements();
0782                } else {
0783                    for (int i = 0; i < size; ++i) {
0784                        Object element = model.getElementAt(0);
0785                        model.removeElement(element);
0786                    }
0787                }
0788                selectedItemReminder = null;
0789                if (isEditable()) {
0790                    editor.setItem(null);
0791                }
0792            }
0793
0794            /** 
0795             * Checks that the <code>dataModel</code> is an instance of 
0796             * <code>MutableComboBoxModel</code>.  If not, it throws an exception.
0797             * @exception RuntimeException if <code>dataModel</code> is not an
0798             *		instance of <code>MutableComboBoxModel</code>.
0799             */
0800            void checkMutableComboBoxModel() {
0801                if (!(dataModel instanceof  MutableComboBoxModel))
0802                    throw new RuntimeException(
0803                            "Cannot use this method with a non-Mutable data model.");
0804            }
0805
0806            /** 
0807             * Causes the combo box to display its popup window.
0808             * @see #setPopupVisible
0809             */
0810            public void showPopup() {
0811                setPopupVisible(true);
0812            }
0813
0814            /** 
0815             * Causes the combo box to close its popup window.
0816             * @see #setPopupVisible
0817             */
0818            public void hidePopup() {
0819                setPopupVisible(false);
0820            }
0821
0822            /**
0823             * Sets the visibility of the popup.
0824             */
0825            public void setPopupVisible(boolean v) {
0826                getUI().setPopupVisible(this , v);
0827            }
0828
0829            /** 
0830             * Determines the visibility of the popup.
0831             *
0832             * @return true if the popup is visible, otherwise returns false
0833             */
0834            public boolean isPopupVisible() {
0835                return getUI().isPopupVisible(this );
0836            }
0837
0838            /** Selection **/
0839
0840            /** 
0841             * Adds an <code>ItemListener</code>.
0842             * <p>
0843             * <code>aListener</code> will receive one or two <code>ItemEvent</code>s when
0844             * the selected item changes.
0845             *
0846             * @param aListener the <code>ItemListener</code> that is to be notified
0847             * @see #setSelectedItem
0848             */
0849            public void addItemListener(ItemListener aListener) {
0850                listenerList.add(ItemListener.class, aListener);
0851            }
0852
0853            /** Removes an <code>ItemListener</code>.
0854             *
0855             * @param aListener  the <code>ItemListener</code> to remove
0856             */
0857            public void removeItemListener(ItemListener aListener) {
0858                listenerList.remove(ItemListener.class, aListener);
0859            }
0860
0861            /**
0862             * Returns an array of all the <code>ItemListener</code>s added
0863             * to this JComboBox with addItemListener().
0864             *
0865             * @return all of the <code>ItemListener</code>s added or an empty
0866             *         array if no listeners have been added
0867             * @since 1.4
0868             */
0869            public ItemListener[] getItemListeners() {
0870                return (ItemListener[]) listenerList
0871                        .getListeners(ItemListener.class);
0872            }
0873
0874            /** 
0875             * Adds an <code>ActionListener</code>. 
0876             * <p>
0877             * The <code>ActionListener</code> will receive an <code>ActionEvent</code>
0878             * when a selection has been made. If the combo box is editable, then
0879             * an <code>ActionEvent</code> will be fired when editing has stopped.
0880             *
0881             * @param l  the <code>ActionListener</code> that is to be notified
0882             * @see #setSelectedItem
0883             */
0884            public void addActionListener(ActionListener l) {
0885                listenerList.add(ActionListener.class, l);
0886            }
0887
0888            /** Removes an <code>ActionListener</code>.
0889             *
0890             * @param l  the <code>ActionListener</code> to remove
0891             */
0892            public void removeActionListener(ActionListener l) {
0893                if ((l != null) && (getAction() == l)) {
0894                    setAction(null);
0895                } else {
0896                    listenerList.remove(ActionListener.class, l);
0897                }
0898            }
0899
0900            /**
0901             * Returns an array of all the <code>ActionListener</code>s added
0902             * to this JComboBox with addActionListener().
0903             *
0904             * @return all of the <code>ActionListener</code>s added or an empty
0905             *         array if no listeners have been added
0906             * @since 1.4
0907             */
0908            public ActionListener[] getActionListeners() {
0909                return (ActionListener[]) listenerList
0910                        .getListeners(ActionListener.class);
0911            }
0912
0913            /**
0914             * Adds a <code>PopupMenu</code> listener which will listen to notification
0915             * messages from the popup portion of the combo box. 
0916             * <p>
0917             * For all standard look and feels shipped with Java, the popup list  
0918             * portion of combo box is implemented as a <code>JPopupMenu</code>.
0919             * A custom look and feel may not implement it this way and will 
0920             * therefore not receive the notification.
0921             *
0922             * @param l  the <code>PopupMenuListener</code> to add
0923             * @since 1.4
0924             */
0925            public void addPopupMenuListener(PopupMenuListener l) {
0926                listenerList.add(PopupMenuListener.class, l);
0927            }
0928
0929            /**
0930             * Removes a <code>PopupMenuListener</code>.
0931             *
0932             * @param l  the <code>PopupMenuListener</code> to remove
0933             * @see #addPopupMenuListener
0934             * @since 1.4
0935             */
0936            public void removePopupMenuListener(PopupMenuListener l) {
0937                listenerList.remove(PopupMenuListener.class, l);
0938            }
0939
0940            /**
0941             * Returns an array of all the <code>PopupMenuListener</code>s added
0942             * to this JComboBox with addPopupMenuListener().
0943             *
0944             * @return all of the <code>PopupMenuListener</code>s added or an empty
0945             *         array if no listeners have been added
0946             * @since 1.4
0947             */
0948            public PopupMenuListener[] getPopupMenuListeners() {
0949                return (PopupMenuListener[]) listenerList
0950                        .getListeners(PopupMenuListener.class);
0951            }
0952
0953            /**
0954             * Notifies <code>PopupMenuListener</code>s that the popup portion of the
0955             * combo box will become visible.
0956             * <p>
0957             * This method is public but should not be called by anything other than 
0958             * the UI delegate.
0959             * @see #addPopupMenuListener
0960             * @since 1.4
0961             */
0962            public void firePopupMenuWillBecomeVisible() {
0963                Object[] listeners = listenerList.getListenerList();
0964                PopupMenuEvent e = null;
0965                for (int i = listeners.length - 2; i >= 0; i -= 2) {
0966                    if (listeners[i] == PopupMenuListener.class) {
0967                        if (e == null)
0968                            e = new PopupMenuEvent(this );
0969                        ((PopupMenuListener) listeners[i + 1])
0970                                .popupMenuWillBecomeVisible(e);
0971                    }
0972                }
0973            }
0974
0975            /**
0976             * Notifies <code>PopupMenuListener</code>s that the popup portion of the
0977             * combo box has become invisible.
0978             * <p>
0979             * This method is public but should not be called by anything other than 
0980             * the UI delegate.
0981             * @see #addPopupMenuListener
0982             * @since 1.4
0983             */
0984            public void firePopupMenuWillBecomeInvisible() {
0985                Object[] listeners = listenerList.getListenerList();
0986                PopupMenuEvent e = null;
0987                for (int i = listeners.length - 2; i >= 0; i -= 2) {
0988                    if (listeners[i] == PopupMenuListener.class) {
0989                        if (e == null)
0990                            e = new PopupMenuEvent(this );
0991                        ((PopupMenuListener) listeners[i + 1])
0992                                .popupMenuWillBecomeInvisible(e);
0993                    }
0994                }
0995            }
0996
0997            /**
0998             * Notifies <code>PopupMenuListener</code>s that the popup portion of the 
0999             * combo box has been canceled.
1000             * <p>
1001             * This method is public but should not be called by anything other than 
1002             * the UI delegate.
1003             * @see #addPopupMenuListener
1004             * @since 1.4
1005             */
1006            public void firePopupMenuCanceled() {
1007                Object[] listeners = listenerList.getListenerList();
1008                PopupMenuEvent e = null;
1009                for (int i = listeners.length - 2; i >= 0; i -= 2) {
1010                    if (listeners[i] == PopupMenuListener.class) {
1011                        if (e == null)
1012                            e = new PopupMenuEvent(this );
1013                        ((PopupMenuListener) listeners[i + 1])
1014                                .popupMenuCanceled(e);
1015                    }
1016                }
1017            }
1018
1019            /** 
1020             * Sets the action command that should be included in the event
1021             * sent to action listeners.
1022             *
1023             * @param aCommand  a string containing the "command" that is sent
1024             *                  to action listeners; the same listener can then
1025             *                  do different things depending on the command it
1026             *                  receives
1027             */
1028            public void setActionCommand(String aCommand) {
1029                actionCommand = aCommand;
1030            }
1031
1032            /** 
1033             * Returns the action command that is included in the event sent to
1034             * action listeners.
1035             *
1036             * @return  the string containing the "command" that is sent
1037             *          to action listeners.
1038             */
1039            public String getActionCommand() {
1040                return actionCommand;
1041            }
1042
1043            private Action action;
1044            private PropertyChangeListener actionPropertyChangeListener;
1045
1046            /**
1047             * Sets the <code>Action</code> for the <code>ActionEvent</code> source.
1048             * The new <code>Action</code> replaces any previously set
1049             * <code>Action</code> but does not affect <code>ActionListeners</code>
1050             * independently added with <code>addActionListener</code>. 
1051             * If the <code>Action</code> is already a registered
1052             * <code>ActionListener</code> for the <code>ActionEvent</code> source,
1053             * it is not re-registered.
1054             * <p>
1055             * Setting the <code>Action</code> results in immediately changing
1056             * all the properties described in <a href="Action.html#buttonActions">
1057             * Swing Components Supporting <code>Action</code></a>.
1058             * Subsequently, the combobox's properties are automatically updated
1059             * as the <code>Action</code>'s properties change.
1060             * <p>
1061             * This method uses three other methods to set
1062             * and help track the <code>Action</code>'s property values.
1063             * It uses the <code>configurePropertiesFromAction</code> method
1064             * to immediately change the combobox's properties.
1065             * To track changes in the <code>Action</code>'s property values,
1066             * this method registers the <code>PropertyChangeListener</code>
1067             * returned by <code>createActionPropertyChangeListener</code>. The
1068             * default {@code PropertyChangeListener} invokes the
1069             * {@code actionPropertyChanged} method when a property in the
1070             * {@code Action} changes. 
1071             *
1072             * @param a the <code>Action</code> for the <code>JComboBox</code>,
1073             *			or <code>null</code>.
1074             * @since 1.3
1075             * @see Action
1076             * @see #getAction
1077             * @see #configurePropertiesFromAction
1078             * @see #createActionPropertyChangeListener
1079             * @see #actionPropertyChanged 
1080             * @beaninfo
1081             *        bound: true
1082             *    attribute: visualUpdate true
1083             *  description: the Action instance connected with this ActionEvent source
1084             */
1085            public void setAction(Action a) {
1086                Action oldValue = getAction();
1087                if (action == null || !action.equals(a)) {
1088                    action = a;
1089                    if (oldValue != null) {
1090                        removeActionListener(oldValue);
1091                        oldValue
1092                                .removePropertyChangeListener(actionPropertyChangeListener);
1093                        actionPropertyChangeListener = null;
1094                    }
1095                    configurePropertiesFromAction(action);
1096                    if (action != null) {
1097                        // Don't add if it is already a listener
1098                        if (!isListener(ActionListener.class, action)) {
1099                            addActionListener(action);
1100                        }
1101                        // Reverse linkage:
1102                        actionPropertyChangeListener = createActionPropertyChangeListener(action);
1103                        action
1104                                .addPropertyChangeListener(actionPropertyChangeListener);
1105                    }
1106                    firePropertyChange("action", oldValue, action);
1107                }
1108            }
1109
1110            private boolean isListener(Class c, ActionListener a) {
1111                boolean isListener = false;
1112                Object[] listeners = listenerList.getListenerList();
1113                for (int i = listeners.length - 2; i >= 0; i -= 2) {
1114                    if (listeners[i] == c && listeners[i + 1] == a) {
1115                        isListener = true;
1116                    }
1117                }
1118                return isListener;
1119            }
1120
1121            /**
1122             * Returns the currently set <code>Action</code> for this
1123             * <code>ActionEvent</code> source, or <code>null</code> if no
1124             * <code>Action</code> is set.
1125             *
1126             * @return the <code>Action</code> for this <code>ActionEvent</code>
1127             *		source; or <code>null</code>
1128             * @since 1.3
1129             * @see Action
1130             * @see #setAction
1131             */
1132            public Action getAction() {
1133                return action;
1134            }
1135
1136            /**
1137             * Sets the properties on this combobox to match those in the specified 
1138             * <code>Action</code>.  Refer to <a href="Action.html#buttonActions">
1139             * Swing Components Supporting <code>Action</code></a> for more
1140             * details as to which properties this sets.
1141             *
1142             * @param a the <code>Action</code> from which to get the properties,
1143             *          or <code>null</code>
1144             * @since 1.3
1145             * @see Action
1146             * @see #setAction
1147             */
1148            protected void configurePropertiesFromAction(Action a) {
1149                AbstractAction.setEnabledFromAction(this , a);
1150                AbstractAction.setToolTipTextFromAction(this , a);
1151                setActionCommandFromAction(a);
1152            }
1153
1154            /**
1155             * Creates and returns a <code>PropertyChangeListener</code> that is
1156             * responsible for listening for changes from the specified
1157             * <code>Action</code> and updating the appropriate properties.
1158             * <p>
1159             * <b>Warning:</b> If you subclass this do not create an anonymous
1160             * inner class.  If you do the lifetime of the combobox will be tied to
1161             * that of the <code>Action</code>.
1162             *
1163             * @param a the combobox's action
1164             * @since 1.3
1165             * @see Action
1166             * @see #setAction
1167             */
1168            protected PropertyChangeListener createActionPropertyChangeListener(
1169                    Action a) {
1170                return new ComboBoxActionPropertyChangeListener(this , a);
1171            }
1172
1173            /**
1174             * Updates the combobox's state in response to property changes in
1175             * associated action. This method is invoked from the
1176             * {@code PropertyChangeListener} returned from
1177             * {@code createActionPropertyChangeListener}. Subclasses do not normally
1178             * need to invoke this. Subclasses that support additional {@code Action}
1179             * properties should override this and
1180             * {@code configurePropertiesFromAction}.
1181             * <p>
1182             * Refer to the table at <a href="Action.html#buttonActions">
1183             * Swing Components Supporting <code>Action</code></a> for a list of
1184             * the properties this method sets.
1185             *
1186             * @param action the <code>Action</code> associated with this combobox
1187             * @param propertyName the name of the property that changed
1188             * @since 1.6
1189             * @see Action
1190             * @see #configurePropertiesFromAction
1191             */
1192            protected void actionPropertyChanged(Action action,
1193                    String propertyName) {
1194                if (propertyName == Action.ACTION_COMMAND_KEY) {
1195                    setActionCommandFromAction(action);
1196                } else if (propertyName == "enabled") {
1197                    AbstractAction.setEnabledFromAction(this , action);
1198                } else if (Action.SHORT_DESCRIPTION == propertyName) {
1199                    AbstractAction.setToolTipTextFromAction(this , action);
1200                }
1201            }
1202
1203            private void setActionCommandFromAction(Action a) {
1204                setActionCommand((a != null) ? (String) a
1205                        .getValue(Action.ACTION_COMMAND_KEY) : null);
1206            }
1207
1208            private static class ComboBoxActionPropertyChangeListener extends
1209                    ActionPropertyChangeListener<JComboBox> {
1210                ComboBoxActionPropertyChangeListener(JComboBox b, Action a) {
1211                    super (b, a);
1212                }
1213
1214                protected void actionPropertyChanged(JComboBox cb,
1215                        Action action, PropertyChangeEvent e) {
1216                    if (AbstractAction.shouldReconfigure(e)) {
1217                        cb.configurePropertiesFromAction(action);
1218                    } else {
1219                        cb.actionPropertyChanged(action, e.getPropertyName());
1220                    }
1221                }
1222            }
1223
1224            /**
1225             * Notifies all listeners that have registered interest for
1226             * notification on this event type.
1227             * @param e  the event of interest
1228             *  
1229             * @see EventListenerList
1230             */
1231            protected void fireItemStateChanged(ItemEvent e) {
1232                // Guaranteed to return a non-null array
1233                Object[] listeners = listenerList.getListenerList();
1234                // Process the listeners last to first, notifying
1235                // those that are interested in this event
1236                for (int i = listeners.length - 2; i >= 0; i -= 2) {
1237                    if (listeners[i] == ItemListener.class) {
1238                        // Lazily create the event:
1239                        // if (changeEvent == null)
1240                        // changeEvent = new ChangeEvent(this);
1241                        ((ItemListener) listeners[i + 1]).itemStateChanged(e);
1242                    }
1243                }
1244            }
1245
1246            /**
1247             * Notifies all listeners that have registered interest for
1248             * notification on this event type.
1249             *  
1250             * @see EventListenerList
1251             */
1252            protected void fireActionEvent() {
1253                if (!firingActionEvent) {
1254                    // Set flag to ensure that an infinite loop is not created
1255                    firingActionEvent = true;
1256                    ActionEvent e = null;
1257                    // Guaranteed to return a non-null array
1258                    Object[] listeners = listenerList.getListenerList();
1259                    long mostRecentEventTime = EventQueue
1260                            .getMostRecentEventTime();
1261                    int modifiers = 0;
1262                    AWTEvent currentEvent = EventQueue.getCurrentEvent();
1263                    if (currentEvent instanceof  InputEvent) {
1264                        modifiers = ((InputEvent) currentEvent).getModifiers();
1265                    } else if (currentEvent instanceof  ActionEvent) {
1266                        modifiers = ((ActionEvent) currentEvent).getModifiers();
1267                    }
1268                    // Process the listeners last to first, notifying
1269                    // those that are interested in this event
1270                    for (int i = listeners.length - 2; i >= 0; i -= 2) {
1271                        if (listeners[i] == ActionListener.class) {
1272                            // Lazily create the event:
1273                            if (e == null)
1274                                e = new ActionEvent(this ,
1275                                        ActionEvent.ACTION_PERFORMED,
1276                                        getActionCommand(),
1277                                        mostRecentEventTime, modifiers);
1278                            ((ActionListener) listeners[i + 1])
1279                                    .actionPerformed(e);
1280                        }
1281                    }
1282                    firingActionEvent = false;
1283                }
1284            }
1285
1286            /**
1287             * This protected method is implementation specific. Do not access directly
1288             * or override. 
1289             */
1290            protected void selectedItemChanged() {
1291                if (selectedItemReminder != null) {
1292                    fireItemStateChanged(new ItemEvent(this ,
1293                            ItemEvent.ITEM_STATE_CHANGED, selectedItemReminder,
1294                            ItemEvent.DESELECTED));
1295                }
1296
1297                // set the new selected item.
1298                selectedItemReminder = dataModel.getSelectedItem();
1299
1300                if (selectedItemReminder != null) {
1301                    fireItemStateChanged(new ItemEvent(this ,
1302                            ItemEvent.ITEM_STATE_CHANGED, selectedItemReminder,
1303                            ItemEvent.SELECTED));
1304                }
1305            }
1306
1307            /** 
1308             * Returns an array containing the selected item.
1309             * This method is implemented for compatibility with
1310             * <code>ItemSelectable</code>.
1311             *
1312             * @return an array of <code>Objects</code> containing one
1313             *		element -- the selected item
1314             */
1315            public Object[] getSelectedObjects() {
1316                Object selectedObject = getSelectedItem();
1317                if (selectedObject == null)
1318                    return new Object[0];
1319                else {
1320                    Object result[] = new Object[1];
1321                    result[0] = selectedObject;
1322                    return result;
1323                }
1324            }
1325
1326            /** 
1327             * This method is public as an implementation side effect. 
1328             * do not call or override. 
1329             */
1330            public void actionPerformed(ActionEvent e) {
1331                Object newItem = getEditor().getItem();
1332                setPopupVisible(false);
1333                getModel().setSelectedItem(newItem);
1334                String oldCommand = getActionCommand();
1335                setActionCommand("comboBoxEdited");
1336                fireActionEvent();
1337                setActionCommand(oldCommand);
1338            }
1339
1340            /**
1341             * This method is public as an implementation side effect. 
1342             * do not call or override. 
1343             */
1344            public void contentsChanged(ListDataEvent e) {
1345                Object oldSelection = selectedItemReminder;
1346                Object newSelection = dataModel.getSelectedItem();
1347                if (oldSelection == null || !oldSelection.equals(newSelection)) {
1348                    selectedItemChanged();
1349                    if (!selectingItem) {
1350                        fireActionEvent();
1351                    }
1352                }
1353            }
1354
1355            /**
1356             * This method is public as an implementation side effect. 
1357             * do not call or override. 
1358             */
1359            public void intervalAdded(ListDataEvent e) {
1360                if (selectedItemReminder != dataModel.getSelectedItem()) {
1361                    selectedItemChanged();
1362                }
1363            }
1364
1365            /**
1366             * This method is public as an implementation side effect. 
1367             * do not call or override. 
1368             */
1369            public void intervalRemoved(ListDataEvent e) {
1370                contentsChanged(e);
1371            }
1372
1373            /**
1374             * Selects the list item that corresponds to the specified keyboard
1375             * character and returns true, if there is an item corresponding
1376             * to that character.  Otherwise, returns false.
1377             *
1378             * @param keyChar a char, typically this is a keyboard key
1379             *			typed by the user
1380             */
1381            public boolean selectWithKeyChar(char keyChar) {
1382                int index;
1383
1384                if (keySelectionManager == null)
1385                    keySelectionManager = createDefaultKeySelectionManager();
1386
1387                index = keySelectionManager
1388                        .selectionForKey(keyChar, getModel());
1389                if (index != -1) {
1390                    setSelectedIndex(index);
1391                    return true;
1392                } else
1393                    return false;
1394            }
1395
1396            /**
1397             * Enables the combo box so that items can be selected. When the
1398             * combo box is disabled, items cannot be selected and values
1399             * cannot be typed into its field (if it is editable).
1400             *
1401             * @param b a boolean value, where true enables the component and
1402             *          false disables it
1403             * @beaninfo
1404             *        bound: true
1405             *    preferred: true
1406             *  description: Whether the combo box is enabled.
1407             */
1408            public void setEnabled(boolean b) {
1409                super .setEnabled(b);
1410                firePropertyChange("enabled", !isEnabled(), isEnabled());
1411            }
1412
1413            /**
1414             * Initializes the editor with the specified item.
1415             *                                 
1416             * @param anEditor the <code>ComboBoxEditor</code> that displays
1417             *			the list item in the
1418             *                 	combo box field and allows it to be edited
1419             * @param anItem   the object to display and edit in the field
1420             */
1421            public void configureEditor(ComboBoxEditor anEditor, Object anItem) {
1422                anEditor.setItem(anItem);
1423            }
1424
1425            /**
1426             * Handles <code>KeyEvent</code>s, looking for the Tab key.
1427             * If the Tab key is found, the popup window is closed.
1428             *
1429             * @param e  the <code>KeyEvent</code> containing the keyboard
1430             *		key that was pressed  
1431             */
1432            public void processKeyEvent(KeyEvent e) {
1433                if (e.getKeyCode() == KeyEvent.VK_TAB) {
1434                    hidePopup();
1435                }
1436                super .processKeyEvent(e);
1437            }
1438
1439            /**
1440             * Sets the object that translates a keyboard character into a list
1441             * selection. Typically, the first selection with a matching first
1442             * character becomes the selected item.
1443             *
1444             * @beaninfo
1445             *       expert: true
1446             *  description: The objects that changes the selection when a key is pressed.
1447             */
1448            public void setKeySelectionManager(KeySelectionManager aManager) {
1449                keySelectionManager = aManager;
1450            }
1451
1452            /**
1453             * Returns the list's key-selection manager.
1454             *
1455             * @return the <code>KeySelectionManager</code> currently in use
1456             */
1457            public KeySelectionManager getKeySelectionManager() {
1458                return keySelectionManager;
1459            }
1460
1461            /* Accessing the model */
1462            /**
1463             * Returns the number of items in the list.
1464             *
1465             * @return an integer equal to the number of items in the list
1466             */
1467            public int getItemCount() {
1468                return dataModel.getSize();
1469            }
1470
1471            /**
1472             * Returns the list item at the specified index.  If <code>index</code>
1473             * is out of range (less than zero or greater than or equal to size)
1474             * it will return <code>null</code>.
1475             *
1476             * @param index  an integer indicating the list position, where the first
1477             *               item starts at zero
1478             * @return the <code>Object</code> at that list position; or
1479             *			<code>null</code> if out of range
1480             */
1481            public Object getItemAt(int index) {
1482                return dataModel.getElementAt(index);
1483            }
1484
1485            /**
1486             * Returns an instance of the default key-selection manager.
1487             *
1488             * @return the <code>KeySelectionManager</code> currently used by the list
1489             * @see #setKeySelectionManager
1490             */
1491            protected KeySelectionManager createDefaultKeySelectionManager() {
1492                return new DefaultKeySelectionManager();
1493            }
1494
1495            /**
1496             * The interface that defines a <code>KeySelectionManager</code>.
1497             * To qualify as a <code>KeySelectionManager</code>,
1498             * the class needs to implement the method
1499             * that identifies the list index given a character and the 
1500             * combo box data model.
1501             */
1502            public interface KeySelectionManager {
1503                /** Given <code>aKey</code> and the model, returns the row
1504                 *  that should become selected. Return -1 if no match was
1505                 *  found. 
1506                 *
1507                 * @param  aKey  a char value, usually indicating a keyboard key that
1508                 *               was pressed
1509                 * @param aModel a ComboBoxModel -- the component's data model, containing
1510                 *               the list of selectable items 
1511                 * @return an int equal to the selected row, where 0 is the
1512                 *         first item and -1 is none. 
1513                 */
1514                int selectionForKey(char aKey, ComboBoxModel aModel);
1515            }
1516
1517            class DefaultKeySelectionManager implements  KeySelectionManager,
1518                    Serializable {
1519                public int selectionForKey(char aKey, ComboBoxModel aModel) {
1520                    int i, c;
1521                    int currentSelection = -1;
1522                    Object selectedItem = aModel.getSelectedItem();
1523                    String v;
1524                    String pattern;
1525
1526                    if (selectedItem != null) {
1527                        for (i = 0, c = aModel.getSize(); i < c; i++) {
1528                            if (selectedItem == aModel.getElementAt(i)) {
1529                                currentSelection = i;
1530                                break;
1531                            }
1532                        }
1533                    }
1534
1535                    pattern = ("" + aKey).toLowerCase();
1536                    aKey = pattern.charAt(0);
1537
1538                    for (i = ++currentSelection, c = aModel.getSize(); i < c; i++) {
1539                        Object elem = aModel.getElementAt(i);
1540                        if (elem != null && elem.toString() != null) {
1541                            v = elem.toString().toLowerCase();
1542                            if (v.length() > 0 && v.charAt(0) == aKey)
1543                                return i;
1544                        }
1545                    }
1546
1547                    for (i = 0; i < currentSelection; i++) {
1548                        Object elem = aModel.getElementAt(i);
1549                        if (elem != null && elem.toString() != null) {
1550                            v = elem.toString().toLowerCase();
1551                            if (v.length() > 0 && v.charAt(0) == aKey)
1552                                return i;
1553                        }
1554                    }
1555                    return -1;
1556                }
1557            }
1558
1559            /** 
1560             * See <code>readObject</code> and <code>writeObject</code> in
1561             * <code>JComponent</code> for more 
1562             * information about serialization in Swing.
1563             */
1564            private void writeObject(ObjectOutputStream s) throws IOException {
1565                s.defaultWriteObject();
1566                if (getUIClassID().equals(uiClassID)) {
1567                    byte count = JComponent.getWriteObjCounter(this );
1568                    JComponent.setWriteObjCounter(this , --count);
1569                    if (count == 0 && ui != null) {
1570                        ui.installUI(this );
1571                    }
1572                }
1573            }
1574
1575            /**
1576             * Returns a string representation of this <code>JComboBox</code>.
1577             * This method is intended to be used only for debugging purposes,
1578             * and the content and format of the returned string may vary between   
1579             * implementations. The returned string may be empty but may not 
1580             * be <code>null</code>.
1581             * 
1582             * @return  a string representation of this <code>JComboBox</code>
1583             */
1584            protected String paramString() {
1585                String selectedItemReminderString = (selectedItemReminder != null ? selectedItemReminder
1586                        .toString()
1587                        : "");
1588                String isEditableString = (isEditable ? "true" : "false");
1589                String lightWeightPopupEnabledString = (lightWeightPopupEnabled ? "true"
1590                        : "false");
1591
1592                return super .paramString() + ",isEditable=" + isEditableString
1593                        + ",lightWeightPopupEnabled="
1594                        + lightWeightPopupEnabledString + ",maximumRowCount="
1595                        + maximumRowCount + ",selectedItemReminder="
1596                        + selectedItemReminderString;
1597            }
1598
1599            ///////////////////
1600            // Accessibility support
1601            ///////////////////
1602
1603            /**
1604             * Gets the AccessibleContext associated with this JComboBox. 
1605             * For combo boxes, the AccessibleContext takes the form of an 
1606             * AccessibleJComboBox. 
1607             * A new AccessibleJComboBox instance is created if necessary.
1608             *
1609             * @return an AccessibleJComboBox that serves as the 
1610             *         AccessibleContext of this JComboBox
1611             */
1612            public AccessibleContext getAccessibleContext() {
1613                if (accessibleContext == null) {
1614                    accessibleContext = new AccessibleJComboBox();
1615                }
1616                return accessibleContext;
1617            }
1618
1619            /**
1620             * This class implements accessibility support for the 
1621             * <code>JComboBox</code> class.  It provides an implementation of the 
1622             * Java Accessibility API appropriate to Combo Box user-interface elements.
1623             * <p>
1624             * <strong>Warning:</strong>
1625             * Serialized objects of this class will not be compatible with
1626             * future Swing releases. The current serialization support is
1627             * appropriate for short term storage or RMI between applications running
1628             * the same version of Swing.  As of 1.4, support for long term storage
1629             * of all JavaBeans<sup><font size="-2">TM</font></sup>
1630             * has been added to the <code>java.beans</code> package.
1631             * Please see {@link java.beans.XMLEncoder}.
1632             */
1633            protected class AccessibleJComboBox extends AccessibleJComponent
1634                    implements  AccessibleAction, AccessibleSelection {
1635
1636                private JList popupList; // combo box popup list
1637                private Accessible previousSelectedAccessible = null;
1638
1639                /**
1640                 * Returns an AccessibleJComboBox instance
1641                 * @since 1.4
1642                 */
1643                public AccessibleJComboBox() {
1644                    // set the combo box editor's accessible name and description
1645                    JComboBox.this 
1646                            .addPropertyChangeListener(new AccessibleJComboBoxPropertyChangeListener());
1647                    setEditorNameAndDescription();
1648
1649                    // Get the popup list
1650                    Accessible a = getUI()
1651                            .getAccessibleChild(JComboBox.this , 0);
1652                    if (a instanceof  javax.swing.plaf.basic.ComboPopup) {
1653                        // Listen for changes to the popup menu selection.
1654                        popupList = ((javax.swing.plaf.basic.ComboPopup) a)
1655                                .getList();
1656                        popupList
1657                                .addListSelectionListener(new AccessibleJComboBoxListSelectionListener());
1658                    }
1659                    // Listen for popup menu show/hide events
1660                    JComboBox.this 
1661                            .addPopupMenuListener(new AccessibleJComboBoxPopupMenuListener());
1662                }
1663
1664                /*
1665                 * JComboBox PropertyChangeListener
1666                 */
1667                private class AccessibleJComboBoxPropertyChangeListener
1668                        implements  PropertyChangeListener {
1669
1670                    public void propertyChange(PropertyChangeEvent e) {
1671                        if (e.getPropertyName() == "editor") {
1672                            // set the combo box editor's accessible name 
1673                            // and description
1674                            setEditorNameAndDescription();
1675                        }
1676                    }
1677                }
1678
1679                /*
1680                 * Sets the combo box editor's accessible name and descripton
1681                 */
1682                private void setEditorNameAndDescription() {
1683                    ComboBoxEditor editor = JComboBox.this .getEditor();
1684                    if (editor != null) {
1685                        Component comp = editor.getEditorComponent();
1686                        if (comp instanceof  Accessible) {
1687                            AccessibleContext ac = ((Accessible) comp)
1688                                    .getAccessibleContext();
1689                            if (ac != null) { // may be null
1690                                ac.setAccessibleName(getAccessibleName());
1691                                ac
1692                                        .setAccessibleDescription(getAccessibleDescription());
1693                            }
1694                        }
1695                    }
1696                }
1697
1698                /*
1699                 * Listener for combo box popup menu
1700                 * TIGER - 4669379 4894434 
1701                 */
1702                private class AccessibleJComboBoxPopupMenuListener implements 
1703                        PopupMenuListener {
1704
1705                    /**
1706                     *  This method is called before the popup menu becomes visible 
1707                     */
1708                    public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
1709                        // save the initial selection
1710                        if (popupList == null) {
1711                            return;
1712                        }
1713                        int selectedIndex = popupList.getSelectedIndex();
1714                        if (selectedIndex < 0) {
1715                            return;
1716                        }
1717                        previousSelectedAccessible = popupList
1718                                .getAccessibleContext().getAccessibleChild(
1719                                        selectedIndex);
1720                    }
1721
1722                    /**
1723                     * This method is called before the popup menu becomes invisible
1724                     * Note that a JPopupMenu can become invisible any time 
1725                     */
1726                    public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
1727                        // ignore
1728                    }
1729
1730                    /**
1731                     * This method is called when the popup menu is canceled
1732                     */
1733                    public void popupMenuCanceled(PopupMenuEvent e) {
1734                        // ignore
1735                    }
1736                }
1737
1738                /*
1739                 * Handles changes to the popup list selection.
1740                 * TIGER - 4669379 4894434 4933143
1741                 */
1742                private class AccessibleJComboBoxListSelectionListener
1743                        implements  ListSelectionListener {
1744
1745                    public void valueChanged(ListSelectionEvent e) {
1746                        if (popupList == null) {
1747                            return;
1748                        }
1749
1750                        // Get the selected popup list item.
1751                        int selectedIndex = popupList.getSelectedIndex();
1752                        if (selectedIndex < 0) {
1753                            return;
1754                        }
1755                        Accessible selectedAccessible = popupList
1756                                .getAccessibleContext().getAccessibleChild(
1757                                        selectedIndex);
1758                        if (selectedAccessible == null) {
1759                            return;
1760                        }
1761
1762                        // Fire a FOCUSED lost PropertyChangeEvent for the
1763                        // previously selected list item.
1764                        PropertyChangeEvent pce = null;
1765
1766                        if (previousSelectedAccessible != null) {
1767                            pce = new PropertyChangeEvent(
1768                                    previousSelectedAccessible,
1769                                    AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
1770                                    AccessibleState.FOCUSED, null);
1771                            firePropertyChange(
1772                                    AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
1773                                    null, pce);
1774                        }
1775                        // Fire a FOCUSED gained PropertyChangeEvent for the
1776                        // currently selected list item.
1777                        pce = new PropertyChangeEvent(selectedAccessible,
1778                                AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
1779                                null, AccessibleState.FOCUSED);
1780                        firePropertyChange(
1781                                AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
1782                                null, pce);
1783
1784                        // Fire the ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY event
1785                        // for the combo box.
1786                        firePropertyChange(
1787                                AccessibleContext.ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY,
1788                                previousSelectedAccessible, selectedAccessible);
1789
1790                        // Save the previous selection.
1791                        previousSelectedAccessible = selectedAccessible;
1792                    }
1793                }
1794
1795                /**
1796                 * Returns the number of accessible children in the object.  If all
1797                 * of the children of this object implement Accessible, than this
1798                 * method should return the number of children of this object.
1799                 *
1800                 * @return the number of accessible children in the object.
1801                 */
1802                public int getAccessibleChildrenCount() {
1803                    // Always delegate to the UI if it exists
1804                    if (ui != null) {
1805                        return ui.getAccessibleChildrenCount(JComboBox.this );
1806                    } else {
1807                        return super .getAccessibleChildrenCount();
1808                    }
1809                }
1810
1811                /**
1812                 * Returns the nth Accessible child of the object.
1813                 * The child at index zero represents the popup.
1814                 * If the combo box is editable, the child at index one
1815                 * represents the editor.
1816                 *
1817                 * @param i zero-based index of child
1818                 * @return the nth Accessible child of the object
1819                 */
1820                public Accessible getAccessibleChild(int i) {
1821                    // Always delegate to the UI if it exists
1822                    if (ui != null) {
1823                        return ui.getAccessibleChild(JComboBox.this , i);
1824                    } else {
1825                        return super .getAccessibleChild(i);
1826                    }
1827                }
1828
1829                /**
1830                 * Get the role of this object.
1831                 *
1832                 * @return an instance of AccessibleRole describing the role of the
1833                 * object
1834                 * @see AccessibleRole
1835                 */
1836                public AccessibleRole getAccessibleRole() {
1837                    return AccessibleRole.COMBO_BOX;
1838                }
1839
1840                /**
1841                 * Gets the state set of this object.  The AccessibleStateSet of 
1842                 * an object is composed of a set of unique AccessibleStates.  
1843                 * A change in the AccessibleStateSet of an object will cause a 
1844                 * PropertyChangeEvent to be fired for the ACCESSIBLE_STATE_PROPERTY 
1845                 * property.
1846                 *
1847                 * @return an instance of AccessibleStateSet containing the 
1848                 * current state set of the object
1849                 * @see AccessibleStateSet
1850                 * @see AccessibleState
1851                 * @see #addPropertyChangeListener
1852                 *
1853                 */
1854                public AccessibleStateSet getAccessibleStateSet() {
1855                    // TIGER - 4489748
1856                    AccessibleStateSet ass = super .getAccessibleStateSet();
1857                    if (ass == null) {
1858                        ass = new AccessibleStateSet();
1859                    }
1860                    if (JComboBox.this .isPopupVisible()) {
1861                        ass.add(AccessibleState.EXPANDED);
1862                    } else {
1863                        ass.add(AccessibleState.COLLAPSED);
1864                    }
1865                    return ass;
1866                }
1867
1868                /**
1869                 * Get the AccessibleAction associated with this object.  In the
1870                 * implementation of the Java Accessibility API for this class, 
1871                 * return this object, which is responsible for implementing the
1872                 * AccessibleAction interface on behalf of itself.
1873                 * 
1874                 * @return this object
1875                 */
1876                public AccessibleAction getAccessibleAction() {
1877                    return this ;
1878                }
1879
1880                /**
1881                 * Return a description of the specified action of the object.
1882                 *
1883                 * @param i zero-based index of the actions
1884                 */
1885                public String getAccessibleActionDescription(int i) {
1886                    if (i == 0) {
1887                        return UIManager.getString("ComboBox.togglePopupText");
1888                    } else {
1889                        return null;
1890                    }
1891                }
1892
1893                /**
1894                 * Returns the number of Actions available in this object.  The 
1895                 * default behavior of a combo box is to have one action.
1896                 *
1897                 * @return 1, the number of Actions in this object
1898                 */
1899                public int getAccessibleActionCount() {
1900                    return 1;
1901                }
1902
1903                /**
1904                 * Perform the specified Action on the object
1905                 *
1906                 * @param i zero-based index of actions
1907                 * @return true if the the action was performed; else false.
1908                 */
1909                public boolean doAccessibleAction(int i) {
1910                    if (i == 0) {
1911                        setPopupVisible(!isPopupVisible());
1912                        return true;
1913                    } else {
1914                        return false;
1915                    }
1916                }
1917
1918                /**
1919                 * Get the AccessibleSelection associated with this object.  In the
1920                 * implementation of the Java Accessibility API for this class, 
1921                 * return this object, which is responsible for implementing the
1922                 * AccessibleSelection interface on behalf of itself.
1923                 * 
1924                 * @return this object
1925                 */
1926                public AccessibleSelection getAccessibleSelection() {
1927                    return this ;
1928                }
1929
1930                /**
1931                 * Returns the number of Accessible children currently selected.
1932                 * If no children are selected, the return value will be 0.
1933                 *
1934                 * @return the number of items currently selected.
1935                 * @since 1.3
1936                 */
1937                public int getAccessibleSelectionCount() {
1938                    Object o = JComboBox.this .getSelectedItem();
1939                    if (o != null) {
1940                        return 1;
1941                    } else {
1942                        return 0;
1943                    }
1944                }
1945
1946                /**
1947                 * Returns an Accessible representing the specified selected child
1948                 * in the popup.  If there isn't a selection, or there are 
1949                 * fewer children selected than the integer passed in, the return
1950                 * value will be null.
1951                 * <p>Note that the index represents the i-th selected child, which
1952                 * is different from the i-th child.
1953                 *
1954                 * @param i the zero-based index of selected children
1955                 * @return the i-th selected child
1956                 * @see #getAccessibleSelectionCount
1957                 * @since 1.3
1958                 */
1959                public Accessible getAccessibleSelection(int i) {
1960                    // Get the popup
1961                    Accessible a = JComboBox.this .getUI().getAccessibleChild(
1962                            JComboBox.this , 0);
1963                    if (a != null
1964                            && a instanceof  javax.swing.plaf.basic.ComboPopup) {
1965
1966                        // get the popup list
1967                        JList list = ((javax.swing.plaf.basic.ComboPopup) a)
1968                                .getList();
1969
1970                        // return the i-th selection in the popup list
1971                        AccessibleContext ac = list.getAccessibleContext();
1972                        if (ac != null) {
1973                            AccessibleSelection as = ac
1974                                    .getAccessibleSelection();
1975                            if (as != null) {
1976                                return as.getAccessibleSelection(i);
1977                            }
1978                        }
1979                    }
1980                    return null;
1981                }
1982
1983                /**
1984                 * Determines if the current child of this object is selected.
1985                 *
1986                 * @return true if the current child of this object is selected; 
1987                 * 		else false
1988                 * @param i the zero-based index of the child in this Accessible
1989                 * object.
1990                 * @see AccessibleContext#getAccessibleChild
1991                 * @since 1.3
1992                 */
1993                public boolean isAccessibleChildSelected(int i) {
1994                    return JComboBox.this .getSelectedIndex() == i;
1995                }
1996
1997                /**
1998                 * Adds the specified Accessible child of the object to the object's
1999                 * selection.  If the object supports multiple selections,
2000                 * the specified child is added to any existing selection, otherwise
2001                 * it replaces any existing selection in the object.  If the
2002                 * specified child is already selected, this method has no effect.
2003                 *
2004                 * @param i the zero-based index of the child
2005                 * @see AccessibleContext#getAccessibleChild
2006                 * @since 1.3
2007                 */
2008                public void addAccessibleSelection(int i) {
2009                    // TIGER - 4856195 
2010                    clearAccessibleSelection();
2011                    JComboBox.this .setSelectedIndex(i);
2012                }
2013
2014                /**
2015                 * Removes the specified child of the object from the object's
2016                 * selection.  If the specified item isn't currently selected, this
2017                 * method has no effect.
2018                 *
2019                 * @param i the zero-based index of the child
2020                 * @see AccessibleContext#getAccessibleChild
2021                 * @since 1.3
2022                 */
2023                public void removeAccessibleSelection(int i) {
2024                    if (JComboBox.this .getSelectedIndex() == i) {
2025                        clearAccessibleSelection();
2026                    }
2027                }
2028
2029                /**
2030                 * Clears the selection in the object, so that no children in the
2031                 * object are selected.
2032                 * @since 1.3
2033                 */
2034                public void clearAccessibleSelection() {
2035                    JComboBox.this .setSelectedIndex(-1);
2036                }
2037
2038                /**
2039                 * Causes every child of the object to be selected
2040                 * if the object supports multiple selections.
2041                 * @since 1.3
2042                 */
2043                public void selectAllAccessibleSelection() {
2044                    // do nothing since multiple selection is not supported
2045                }
2046
2047                //        public Accessible getAccessibleAt(Point p) {
2048                //            Accessible a = getAccessibleChild(1);
2049                //            if ( a != null ) {
2050                //                return a; // the editor
2051                //            }
2052                //            else {
2053                //                return getAccessibleChild(0); // the list
2054                //            }
2055                //        }
2056                private EditorAccessibleContext editorAccessibleContext = null;
2057
2058                private class AccessibleEditor implements  Accessible {
2059                    public AccessibleContext getAccessibleContext() {
2060                        if (editorAccessibleContext == null) {
2061                            Component c = JComboBox.this .getEditor()
2062                                    .getEditorComponent();
2063                            if (c instanceof  Accessible) {
2064                                editorAccessibleContext = new EditorAccessibleContext(
2065                                        (Accessible) c);
2066                            }
2067                        }
2068                        return editorAccessibleContext;
2069                    }
2070                }
2071
2072                /*
2073                 * Wrapper class for the AccessibleContext implemented by the
2074                 * combo box editor.  Delegates all method calls except
2075                 * getAccessibleIndexInParent to the editor.  The 
2076                 * getAccessibleIndexInParent method returns the selected 
2077                 * index in the combo box.
2078                 */
2079                private class EditorAccessibleContext extends AccessibleContext {
2080
2081                    private AccessibleContext ac;
2082
2083                    private EditorAccessibleContext() {
2084                    }
2085
2086                    /*
2087                     * @param a the AccessibleContext implemented by the
2088                     * combo box editor
2089                     */
2090                    EditorAccessibleContext(Accessible a) {
2091                        this .ac = a.getAccessibleContext();
2092                    }
2093
2094                    /**
2095                     * Gets the accessibleName property of this object.  The accessibleName
2096                     * property of an object is a localized String that designates the purpose
2097                     * of the object.  For example, the accessibleName property of a label
2098                     * or button might be the text of the label or button itself.  In the
2099                     * case of an object that doesn't display its name, the accessibleName
2100                     * should still be set.  For example, in the case of a text field used
2101                     * to enter the name of a city, the accessibleName for the en_US locale
2102                     * could be 'city.'
2103                     *
2104                     * @return the localized name of the object; null if this 
2105                     * object does not have a name
2106                     *
2107                     * @see #setAccessibleName
2108                     */
2109                    public String getAccessibleName() {
2110                        return ac.getAccessibleName();
2111                    }
2112
2113                    /**
2114                     * Sets the localized accessible name of this object.  Changing the
2115                     * name will cause a PropertyChangeEvent to be fired for the
2116                     * ACCESSIBLE_NAME_PROPERTY property.
2117                     *
2118                     * @param s the new localized name of the object.
2119                     *
2120                     * @see #getAccessibleName
2121                     * @see #addPropertyChangeListener
2122                     *
2123                     * @beaninfo
2124                     *    preferred:   true
2125                     *    description: Sets the accessible name for the component.
2126                     */
2127                    public void setAccessibleName(String s) {
2128                        ac.setAccessibleName(s);
2129                    }
2130
2131                    /**
2132                     * Gets the accessibleDescription property of this object.  The
2133                     * accessibleDescription property of this object is a short localized
2134                     * phrase describing the purpose of the object.  For example, in the 
2135                     * case of a 'Cancel' button, the accessibleDescription could be
2136                     * 'Ignore changes and close dialog box.'
2137                     *
2138                     * @return the localized description of the object; null if 
2139                     * this object does not have a description
2140                     *
2141                     * @see #setAccessibleDescription
2142                     */
2143                    public String getAccessibleDescription() {
2144                        return ac.getAccessibleDescription();
2145                    }
2146
2147                    /**
2148                     * Sets the accessible description of this object.  Changing the
2149                     * name will cause a PropertyChangeEvent to be fired for the
2150                     * ACCESSIBLE_DESCRIPTION_PROPERTY property.
2151                     *
2152                     * @param s the new localized description of the object
2153                     *
2154                     * @see #setAccessibleName
2155                     * @see #addPropertyChangeListener
2156                     *
2157                     * @beaninfo
2158                     *    preferred:   true
2159                     *    description: Sets the accessible description for the component.
2160                     */
2161                    public void setAccessibleDescription(String s) {
2162                        ac.setAccessibleDescription(s);
2163                    }
2164
2165                    /**
2166                     * Gets the role of this object.  The role of the object is the generic
2167                     * purpose or use of the class of this object.  For example, the role
2168                     * of a push button is AccessibleRole.PUSH_BUTTON.  The roles in 
2169                     * AccessibleRole are provided so component developers can pick from
2170                     * a set of predefined roles.  This enables assistive technologies to
2171                     * provide a consistent interface to various tweaked subclasses of 
2172                     * components (e.g., use AccessibleRole.PUSH_BUTTON for all components
2173                     * that act like a push button) as well as distinguish between sublasses
2174                     * that behave differently (e.g., AccessibleRole.CHECK_BOX for check boxes
2175                     * and AccessibleRole.RADIO_BUTTON for radio buttons).
2176                     * <p>Note that the AccessibleRole class is also extensible, so 
2177                     * custom component developers can define their own AccessibleRole's
2178                     * if the set of predefined roles is inadequate.
2179                     *
2180                     * @return an instance of AccessibleRole describing the role of the object
2181                     * @see AccessibleRole
2182                     */
2183                    public AccessibleRole getAccessibleRole() {
2184                        return ac.getAccessibleRole();
2185                    }
2186
2187                    /**
2188                     * Gets the state set of this object.  The AccessibleStateSet of an object
2189                     * is composed of a set of unique AccessibleStates.  A change in the 
2190                     * AccessibleStateSet of an object will cause a PropertyChangeEvent to 
2191                     * be fired for the ACCESSIBLE_STATE_PROPERTY property.
2192                     *
2193                     * @return an instance of AccessibleStateSet containing the 
2194                     * current state set of the object
2195                     * @see AccessibleStateSet
2196                     * @see AccessibleState
2197                     * @see #addPropertyChangeListener
2198                     */
2199                    public AccessibleStateSet getAccessibleStateSet() {
2200                        return ac.getAccessibleStateSet();
2201                    }
2202
2203                    /**
2204                     * Gets the Accessible parent of this object.
2205                     *
2206                     * @return the Accessible parent of this object; null if this
2207                     * object does not have an Accessible parent
2208                     */
2209                    public Accessible getAccessibleParent() {
2210                        return ac.getAccessibleParent();
2211                    }
2212
2213                    /**
2214                     * Sets the Accessible parent of this object.  This is meant to be used
2215                     * only in the situations where the actual component's parent should 
2216                     * not be treated as the component's accessible parent and is a method 
2217                     * that should only be called by the parent of the accessible child. 
2218                     *
2219                     * @param a - Accessible to be set as the parent	
2220                     */
2221                    public void setAccessibleParent(Accessible a) {
2222                        ac.setAccessibleParent(a);
2223                    }
2224
2225                    /**
2226                     * Gets the 0-based index of this object in its accessible parent.
2227                     *
2228                     * @return the 0-based index of this object in its parent; -1 if this 
2229                     * object does not have an accessible parent.
2230                     *
2231                     * @see #getAccessibleParent 
2232                     * @see #getAccessibleChildrenCount
2233                     * @see #getAccessibleChild
2234                     */
2235                    public int getAccessibleIndexInParent() {
2236                        return JComboBox.this .getSelectedIndex();
2237                    }
2238
2239                    /**
2240                     * Returns the number of accessible children of the object.
2241                     *
2242                     * @return the number of accessible children of the object.
2243                     */
2244                    public int getAccessibleChildrenCount() {
2245                        return ac.getAccessibleChildrenCount();
2246                    }
2247
2248                    /**
2249                     * Returns the specified Accessible child of the object.  The Accessible
2250                     * children of an Accessible object are zero-based, so the first child 
2251                     * of an Accessible child is at index 0, the second child is at index 1,
2252                     * and so on.
2253                     *
2254                     * @param i zero-based index of child
2255                     * @return the Accessible child of the object
2256                     * @see #getAccessibleChildrenCount
2257                     */
2258                    public Accessible getAccessibleChild(int i) {
2259                        return ac.getAccessibleChild(i);
2260                    }
2261
2262                    /** 
2263                     * Gets the locale of the component. If the component does not have a 
2264                     * locale, then the locale of its parent is returned.  
2265                     *
2266                     * @return this component's locale.  If this component does not have 
2267                     * a locale, the locale of its parent is returned.
2268                     *
2269                     * @exception IllegalComponentStateException 
2270                     * If the Component does not have its own locale and has not yet been 
2271                     * added to a containment hierarchy such that the locale can be
2272                     * determined from the containing parent. 
2273                     */
2274                    public Locale getLocale()
2275                            throws IllegalComponentStateException {
2276                        return ac.getLocale();
2277                    }
2278
2279                    /**
2280                     * Adds a PropertyChangeListener to the listener list.
2281                     * The listener is registered for all Accessible properties and will
2282                     * be called when those properties change.
2283                     *
2284                     * @see #ACCESSIBLE_NAME_PROPERTY
2285                     * @see #ACCESSIBLE_DESCRIPTION_PROPERTY
2286                     * @see #ACCESSIBLE_STATE_PROPERTY
2287                     * @see #ACCESSIBLE_VALUE_PROPERTY
2288                     * @see #ACCESSIBLE_SELECTION_PROPERTY
2289                     * @see #ACCESSIBLE_TEXT_PROPERTY
2290                     * @see #ACCESSIBLE_VISIBLE_DATA_PROPERTY
2291                     *
2292                     * @param listener  The PropertyChangeListener to be added
2293                     */
2294                    public void addPropertyChangeListener(
2295                            PropertyChangeListener listener) {
2296                        ac.addPropertyChangeListener(listener);
2297                    }
2298
2299                    /**
2300                     * Removes a PropertyChangeListener from the listener list.
2301                     * This removes a PropertyChangeListener that was registered
2302                     * for all properties.
2303                     *
2304                     * @param listener  The PropertyChangeListener to be removed
2305                     */
2306                    public void removePropertyChangeListener(
2307                            PropertyChangeListener listener) {
2308                        ac.removePropertyChangeListener(listener);
2309                    }
2310
2311                    /**
2312                     * Gets the AccessibleAction associated with this object that supports
2313                     * one or more actions. 
2314                     *
2315                     * @return AccessibleAction if supported by object; else return null
2316                     * @see AccessibleAction
2317                     */
2318                    public AccessibleAction getAccessibleAction() {
2319                        return ac.getAccessibleAction();
2320                    }
2321
2322                    /**
2323                     * Gets the AccessibleComponent associated with this object that has a 
2324                     * graphical representation.
2325                     *
2326                     * @return AccessibleComponent if supported by object; else return null
2327                     * @see AccessibleComponent
2328                     */
2329                    public AccessibleComponent getAccessibleComponent() {
2330                        return ac.getAccessibleComponent();
2331                    }
2332
2333                    /**
2334                     * Gets the AccessibleSelection associated with this object which allows its
2335                     * Accessible children to be selected.  
2336                     * 
2337                     * @return AccessibleSelection if supported by object; else return null
2338                     * @see AccessibleSelection
2339                     */
2340                    public AccessibleSelection getAccessibleSelection() {
2341                        return ac.getAccessibleSelection();
2342                    }
2343
2344                    /**
2345                     * Gets the AccessibleText associated with this object presenting 
2346                     * text on the display.
2347                     *
2348                     * @return AccessibleText if supported by object; else return null
2349                     * @see AccessibleText
2350                     */
2351                    public AccessibleText getAccessibleText() {
2352                        return ac.getAccessibleText();
2353                    }
2354
2355                    /**
2356                     * Gets the AccessibleEditableText associated with this object 
2357                     * presenting editable text on the display.
2358                     *
2359                     * @return AccessibleEditableText if supported by object; else return null
2360                     * @see AccessibleEditableText
2361                     */
2362                    public AccessibleEditableText getAccessibleEditableText() {
2363                        return ac.getAccessibleEditableText();
2364                    }
2365
2366                    /**
2367                     * Gets the AccessibleValue associated with this object that supports a 
2368                     * Numerical value. 
2369                     * 
2370                     * @return AccessibleValue if supported by object; else return null 
2371                     * @see AccessibleValue
2372                     */
2373                    public AccessibleValue getAccessibleValue() {
2374                        return ac.getAccessibleValue();
2375                    }
2376
2377                    /**
2378                     * Gets the AccessibleIcons associated with an object that has
2379                     * one or more associated icons
2380                     * 
2381                     * @return an array of AccessibleIcon if supported by object; 
2382                     * otherwise return null 
2383                     * @see AccessibleIcon
2384                     */
2385                    public AccessibleIcon[] getAccessibleIcon() {
2386                        return ac.getAccessibleIcon();
2387                    }
2388
2389                    /**
2390                     * Gets the AccessibleRelationSet associated with an object
2391                     * 
2392                     * @return an AccessibleRelationSet if supported by object;
2393                     * otherwise return null
2394                     * @see AccessibleRelationSet
2395                     */
2396                    public AccessibleRelationSet getAccessibleRelationSet() {
2397                        return ac.getAccessibleRelationSet();
2398                    }
2399
2400                    /**
2401                     * Gets the AccessibleTable associated with an object
2402                     * 
2403                     * @return an AccessibleTable if supported by object;
2404                     * otherwise return null
2405                     * @see AccessibleTable
2406                     */
2407                    public AccessibleTable getAccessibleTable() {
2408                        return ac.getAccessibleTable();
2409                    }
2410
2411                    /**
2412                     * Support for reporting bound property changes.  If oldValue and 
2413                     * newValue are not equal and the PropertyChangeEvent listener list 
2414                     * is not empty, then fire a PropertyChange event to each listener.
2415                     * In general, this is for use by the Accessible objects themselves
2416                     * and should not be called by an application program.
2417                     * @param propertyName  The programmatic name of the property that
2418                     * was changed.
2419                     * @param oldValue  The old value of the property.
2420                     * @param newValue  The new value of the property.
2421                     * @see java.beans.PropertyChangeSupport
2422                     * @see #addPropertyChangeListener
2423                     * @see #removePropertyChangeListener
2424                     * @see #ACCESSIBLE_NAME_PROPERTY
2425                     * @see #ACCESSIBLE_DESCRIPTION_PROPERTY
2426                     * @see #ACCESSIBLE_STATE_PROPERTY
2427                     * @see #ACCESSIBLE_VALUE_PROPERTY
2428                     * @see #ACCESSIBLE_SELECTION_PROPERTY
2429                     * @see #ACCESSIBLE_TEXT_PROPERTY
2430                     * @see #ACCESSIBLE_VISIBLE_DATA_PROPERTY
2431                     */
2432                    public void firePropertyChange(String propertyName,
2433                            Object oldValue, Object newValue) {
2434                        ac.firePropertyChange(propertyName, oldValue, newValue);
2435                    }
2436                }
2437
2438            } // innerclass AccessibleJComboBox
2439        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.