home *** CD-ROM | disk | FTP | other *** search
/ Apple Developer Connection Student Program / ADC Tools Sampler CD Disk 3 1999.iso / Metrowerks CodeWarrior / Java Support / Java_Source / Java2 / src / java / awt / Choice.java < prev    next >
Encoding:
Java Source  |  1999-05-28  |  16.0 KB  |  560 lines  |  [TEXT/CWIE]

  1. /*
  2.  * @(#)Choice.java    1.53 98/08/19
  3.  *
  4.  * Copyright 1995-1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  *
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14. package java.awt;
  15.  
  16. import java.util.*;
  17. import java.awt.peer.ChoicePeer;
  18. import java.awt.event.*;
  19. import java.io.ObjectOutputStream;
  20. import java.io.ObjectInputStream;
  21. import java.io.IOException;
  22.  
  23.  
  24. /**
  25.  * The <code>Choice</code> class presents a pop-up menu of choices.
  26.  * The current choice is displayed as the title of the menu.
  27.  * <p>
  28.  * The following code example produces a pop-up menu:
  29.  * <p>
  30.  * <hr><blockquote><pre>
  31.  * Choice ColorChooser = new Choice();
  32.  * ColorChooser.add("Green");
  33.  * ColorChooser.add("Red");
  34.  * ColorChooser.add("Blue");
  35.  * </pre></blockquote><hr>
  36.  * <p>
  37.  * After this choice menu has been added to a panel,
  38.  * it appears as follows in its normal state:
  39.  * <p>
  40.  * <img src="doc-files/Choice-1.gif"
  41.  * ALIGN=center HSPACE=10 VSPACE=7>
  42.  * <p>
  43.  * In the picture, <code>"Green"</code> is the current choice.
  44.  * Pushing the mouse button down on the object causes a menu to
  45.  * appear with the current choice highlighted.
  46.  * <p>
  47.  * @version    1.53 08/19/98
  48.  * @author     Sami Shaio
  49.  * @author     Arthur van Hoff
  50.  * @since       JDK1.0
  51.  */
  52. public class Choice extends Component implements ItemSelectable {
  53.     /**
  54.      * The items for the Choice.
  55.      * This can be a null value.
  56.      * @serial
  57.      * @see add()
  58.      * @see addItem()
  59.      * @see getItem()
  60.      * @see getItemCount()
  61.      * @see insert()
  62.      * @see remove()
  63.      */
  64.     Vector pItems;
  65.  
  66.     /**
  67.      * The index of the current choice for this Choice.
  68.      * @serial
  69.      * @see getSelectedItem
  70.      * @see select()
  71.      */
  72.     int selectedIndex = -1;
  73.  
  74.     transient ItemListener itemListener;
  75.  
  76.     private static final String base = "choice";
  77.     private static int nameCounter = 0;
  78.  
  79.     /*
  80.      * JDK 1.1 serialVersionUID
  81.      */
  82.      private static final long serialVersionUID = -4075310674757313071L;
  83.  
  84.     /**
  85.      * Creates a new choice menu. The menu initially has no items in it.
  86.      * <p>
  87.      * By default, the first item added to the choice menu becomes the
  88.      * selected item, until a different selection is made by the user
  89.      * by calling one of the <code>select</code> methods.
  90.      * @see       java.awt.Choice#select(int)
  91.      * @see       java.awt.Choice#select(java.lang.String)
  92.      */
  93.     public Choice() {
  94.     pItems = new Vector();
  95.     }
  96.  
  97.     /**
  98.      * Construct a name for this component.  Called by getName() when the
  99.      * name is null.
  100.      */
  101.     String constructComponentName() {
  102.         synchronized (getClass()) {
  103.         return base + nameCounter++;
  104.     }
  105.     }
  106.  
  107.     /**
  108.      * Creates the Choice's peer.  This peer allows us to change the look
  109.      * of the Choice without changing its functionality.
  110.      * @see     java.awt.Toolkit#createChoice(java.awt.Choice)
  111.      * @see     java.awt.Component#getToolkit()
  112.      */
  113.     public void addNotify() {
  114.         synchronized (getTreeLock()) {
  115.         if (peer == null)
  116.             peer = getToolkit().createChoice(this);
  117.         super.addNotify();
  118.     }
  119.     }
  120.  
  121.     /**
  122.      * Returns the number of items in this <code>Choice</code> menu.
  123.      * @see     java.awt.Choice#getItem
  124.      * @since   JDK1.1
  125.      */
  126.     public int getItemCount() {
  127.     return countItems();
  128.     }
  129.  
  130.     /**
  131.      * @deprecated As of JDK version 1.1,
  132.      * replaced by <code>getItemCount()</code>.
  133.      */
  134.     public int countItems() {
  135.     return pItems.size();
  136.     }
  137.  
  138.     /**
  139.      * Gets the string at the specified index in this
  140.      * <code>Choice</code> menu.
  141.      * @param      index the index at which to begin.
  142.      * @see        java.awt.Choice#getItemCount
  143.      */
  144.     public String getItem(int index) {
  145.     return getItemImpl(index);
  146.     }
  147.  
  148.     /*
  149.      * This is called by the native code, so client code can't
  150.      * be called on the toolkit thread.
  151.      */
  152.     final String getItemImpl(int index) {
  153.     return (String)pItems.elementAt(index);
  154.     }
  155.  
  156.     /**
  157.      * Adds an item to this <code>Choice</code> menu.
  158.      * @param      item    the item to be added
  159.      * @exception  NullPointerException   if the item's value is <code>null</code>.
  160.      * @since      JDK1.1
  161.      */
  162.     public void add(String item) {
  163.     addItem(item);
  164.     }
  165.  
  166.     /**
  167.      * Adds an item to this Choice.
  168.      * @param item the item to be added
  169.      * @exception NullPointerException If the item's value is equal to null.
  170.      */
  171.     public void addItem(String item) {
  172.         synchronized (this) {
  173.         addItemNoInvalidate(item);
  174.     }
  175.  
  176.     // This could change the preferred size of the Component.
  177.     if (valid) {
  178.         invalidate();
  179.     }
  180.     }
  181.  
  182.     /**
  183.      * Adds an item to this Choice, but does not invalidate the Choice.
  184.      * Client methods must provide their own synchronization before
  185.      * invoking this method.
  186.      * @param item the item to be added
  187.      * @exception NullPointerException If the item's value is equal to null.
  188.      */
  189.     private void addItemNoInvalidate(String item) {
  190.         if (item == null) {
  191.         throw new 
  192.             NullPointerException("cannot add null item to Choice");
  193.     }
  194.     pItems.addElement(item);
  195.     ChoicePeer peer = (ChoicePeer)this.peer;
  196.     if (peer != null) {
  197.         peer.addItem(item, pItems.size() - 1);
  198.     }
  199.     if (selectedIndex < 0) {
  200.         select(0);
  201.     }
  202.     }
  203.  
  204.  
  205.     /**
  206.      * Inserts the item into this choice at the specified position.
  207.      * @param item the item to be inserted
  208.      * @param index the position at which the item should be inserted
  209.      * @exception IllegalArgumentException if index is less than 0.
  210.      */
  211.     public void insert(String item, int index) {
  212.         synchronized (this) {
  213.         if (index < 0) {
  214.             throw new IllegalArgumentException("index less than zero.");
  215.         }
  216.  
  217.         int nitems = getItemCount();
  218.         Vector tempItems = new Vector();
  219.  
  220.         /* Remove the item at index, nitems-index times 
  221.            storing them in a temporary vector in the
  222.            order they appear on the choice menu.
  223.         */
  224.         for (int i = index ; i < nitems; i++) {
  225.             tempItems.addElement(getItem(index));
  226.         removeNoInvalidate(index);
  227.         }
  228.  
  229.         addItemNoInvalidate(item);
  230.  
  231.         /* Add the removed items back to the choice menu, they 
  232.            are already in the correct order in the temp vector.
  233.         */
  234.         for (int i = 0; i < tempItems.size()  ; i++) {
  235.             addItemNoInvalidate((String)tempItems.elementAt(i));
  236.         }
  237.     }
  238.  
  239.     // This could change the preferred size of the Component.
  240.     if (valid) {
  241.         invalidate();
  242.     }
  243.     }
  244.  
  245.     /**
  246.      * Remove the first occurrence of <code>item</code>
  247.      * from the <code>Choice</code> menu.
  248.      * @param      item  the item to remove from this <code>Choice</code> menu.
  249.      * @exception  IllegalArgumentException  if the item doesn't
  250.      *                     exist in the choice menu.
  251.      * @since      JDK1.1
  252.      */
  253.     public void remove(String item) {
  254.         synchronized (this) {
  255.         int index = pItems.indexOf(item);
  256.         if (index < 0) {
  257.             throw new IllegalArgumentException("item " + item +
  258.                            " not found in choice");
  259.         } else {
  260.             removeNoInvalidate(index);
  261.         }
  262.     }
  263.  
  264.     // This could change the preferred size of the Component.
  265.     if (valid) {
  266.         invalidate();
  267.     }
  268.     }
  269.  
  270.     /**
  271.      * Removes an item from the choice menu
  272.      * at the specified position.
  273.      * @param      position the position of the item.
  274.      * @since      JDK1.1
  275.      */
  276.     public void remove(int position) {
  277.         synchronized (this) {
  278.         removeNoInvalidate(position);
  279.     }
  280.  
  281.     // This could change the preferred size of the Component.
  282.     if (valid) {
  283.         invalidate();
  284.     }
  285.     }
  286.  
  287.     /**
  288.      * Removes an item from the Choice at the specified position, but
  289.      * does not invalidate the Choice. Client methods must provide their
  290.      * own synchronization before invoking this method.
  291.      * @param      position the position of the item.
  292.      */
  293.     private void removeNoInvalidate(int position) {
  294.         pItems.removeElementAt(position);
  295.     ChoicePeer peer = (ChoicePeer)this.peer;
  296.     if (peer != null) {
  297.         peer.remove(position);
  298.     }
  299.     /* Adjust selectedIndex if selected item was removed. */
  300.     if (pItems.size() == 0) {
  301.         selectedIndex = -1;
  302.     } else if (selectedIndex == position) {
  303.         select(0);
  304.     } else if (selectedIndex > position) {
  305.         select(selectedIndex-1);
  306.     }
  307.     }
  308.  
  309.  
  310.     /**
  311.      * Removes all items from the choice menu.
  312.      * @see       java.awt.Choice#remove
  313.      * @since     JDK1.1
  314.      */
  315.     public void removeAll() {
  316.         synchronized (this) {
  317.         int nitems = getItemCount();
  318.         for (int i = 0 ; i < nitems ; i++) {
  319.             removeNoInvalidate(0);
  320.         }
  321.     }
  322.  
  323.     // This could change the preferred size of the Component.
  324.     if (valid) {
  325.         invalidate();
  326.     }
  327.     }
  328.  
  329.     /**
  330.      * Gets a representation of the current choice as a string.
  331.      * @return    a string representation of the currently
  332.      *                     selected item in this choice menu.
  333.      * @see       java.awt.Choice#getSelectedIndex
  334.      */
  335.     public synchronized String getSelectedItem() {
  336.     return (selectedIndex >= 0) ? getItem(selectedIndex) : null;
  337.     }
  338.  
  339.     /**
  340.      * Returns an array (length 1) containing the currently selected
  341.      * item.  If this choice has no items, returns null.
  342.      * @see ItemSelectable
  343.      */
  344.     public synchronized Object[] getSelectedObjects() {
  345.     if (selectedIndex >= 0) {
  346.             Object[] items = new Object[1];
  347.             items[0] = getItem(selectedIndex);
  348.             return items;
  349.         }
  350.         return null;
  351.     }
  352.  
  353.     /**
  354.      * Returns the index of the currently selected item.
  355.      * @see #getSelectedItem
  356.      */
  357.     public int getSelectedIndex() {
  358.     return selectedIndex;
  359.     }
  360.  
  361.     /**
  362.      * Sets the selected item in this <code>Choice</code> menu to be the
  363.      * item at the specified position.
  364.      * @param      pos      the positon of the selected item.
  365.      * @exception  IllegalArgumentException if the specified
  366.      *                            position is invalid.
  367.      * @see        java.awt.Choice#getSelectedItem
  368.      * @see        java.awt.Choice#getSelectedIndex
  369.      */
  370.     public synchronized void select(int pos) {
  371.     if ((pos >= pItems.size()) || (pos < 0)) {
  372.         throw new IllegalArgumentException("illegal Choice item position: " + pos);
  373.     }
  374.     if (pItems.size() > 0) {
  375.         selectedIndex = pos;
  376.         ChoicePeer peer = (ChoicePeer)this.peer;
  377.         if (peer != null) {
  378.         peer.select(pos);
  379.         }
  380.     }
  381.     }
  382.  
  383.     /**
  384.      * Sets the selected item in this <code>Choice</code> menu
  385.      * to be the item whose name is equal to the specified string.
  386.      * If more than one item matches (is equal to) the specified string,
  387.      * the one with the smallest index is selected.
  388.      * @param       str     the specified string
  389.      * @see         java.awt.Choice#getSelectedItem
  390.      * @see         java.awt.Choice#getSelectedIndex
  391.      */
  392.     public synchronized void select(String str) {
  393.     int index = pItems.indexOf(str);
  394.     if (index >= 0) {
  395.         select(index);
  396.     }
  397.     }
  398.  
  399.     /**
  400.      * Adds the specified item listener to receive item events from
  401.      * this <code>Choice</code> menu.
  402.      * If l is null, no exception is thrown and no action is performed.
  403.      * @param         l    the item listener.
  404.      * @see           java.awt.event.ItemEvent
  405.      * @see           java.awt.event.ItemListener
  406.      * @see           java.awt.Choice#removeItemListener
  407.      * @since         JDK1.1
  408.      */
  409.     public synchronized void addItemListener(ItemListener l) {
  410.     if (l == null) {
  411.        return;
  412.     }
  413.         itemListener = AWTEventMulticaster.add(itemListener, l);
  414.         newEventsOnly = true;
  415.     }
  416.  
  417.     /**
  418.      * Removes the specified item listener so that it no longer receives
  419.      * item events from this <code>Choice</code> menu.
  420.      * If l is null, no exception is thrown and no action is performed.
  421.      * @param         l    the item listener.
  422.      * @see           java.awt.event.ItemEvent
  423.      * @see           java.awt.event.ItemListener
  424.      * @see           java.awt.Choice#addItemListener
  425.      * @since         JDK1.1
  426.      */
  427.     public synchronized void removeItemListener(ItemListener l) {
  428.     if (l == null) {
  429.         return;
  430.     }
  431.         itemListener = AWTEventMulticaster.remove(itemListener, l);
  432.     }
  433.  
  434.     // REMIND: remove when filtering is done at lower level
  435.     boolean eventEnabled(AWTEvent e) {
  436.         if (e.id == ItemEvent.ITEM_STATE_CHANGED) {
  437.             if ((eventMask & AWTEvent.ITEM_EVENT_MASK) != 0 ||
  438.                 itemListener != null) {
  439.                 return true;
  440.             }
  441.             return false;
  442.         }
  443.         return super.eventEnabled(e);
  444.     }
  445.  
  446.     /**
  447.      * Processes events on this choice. If the event is an
  448.      * instance of <code>ItemEvent</code>, it invokes the
  449.      * <code>processItemEvent</code> method. Otherwise, it calls its
  450.      * superclass's <code>processEvent</code> method.
  451.      * @param      e the event.
  452.      * @see        java.awt.event.ItemEvent
  453.      * @see        java.awt.Choice#processItemEvent
  454.      * @since      JDK1.1
  455.      */
  456.     protected void processEvent(AWTEvent e) {
  457.         if (e instanceof ItemEvent) {
  458.             processItemEvent((ItemEvent)e);
  459.             return;
  460.         }
  461.     super.processEvent(e);
  462.     }
  463.  
  464.     /**
  465.      * Processes item events occurring on this <code>Choice</code>
  466.      * menu by dispatching them to any registered
  467.      * <code>ItemListener</code> objects.
  468.      * <p>
  469.      * This method is not called unless item events are
  470.      * enabled for this component. Item events are enabled
  471.      * when one of the following occurs:
  472.      * <p><ul>
  473.      * <li>An <code>ItemListener</code> object is registered
  474.      * via <code>addItemListener</code>.
  475.      * <li>Item events are enabled via <code>enableEvents</code>.
  476.      * </ul>
  477.      * @param       e the item event.
  478.      * @see         java.awt.event.ItemEvent
  479.      * @see         java.awt.event.ItemListener
  480.      * @see         java.awt.Choice#addItemListener
  481.      * @see         java.awt.Component#enableEvents
  482.      * @since       JDK1.1
  483.      */
  484.     protected void processItemEvent(ItemEvent e) {
  485.         if (itemListener != null) {
  486.             itemListener.itemStateChanged(e);
  487.         }
  488.     }
  489.  
  490.     /**
  491.      * Returns the parameter string representing the state of this
  492.      * choice menu. This string is useful for debugging.
  493.      * @return    the parameter string of this <code>Choice</code> menu.
  494.      */
  495.     protected String paramString() {
  496.     return super.paramString() + ",current=" + getSelectedItem();
  497.     }
  498.  
  499.  
  500.     /* Serialization support.
  501.      */
  502.  
  503.     /*
  504.     * Choice Serial Data Version.
  505.     * @serial
  506.     */
  507.     private int choiceSerializedDataVersion = 1;
  508.  
  509.     /**
  510.     * Writes default serializable fields to stream.  Writes
  511.     * a list of serializable ItemListener(s) as optional data.
  512.     * The non-serializable ItemListner(s) are detected and
  513.     * no attempt is made to serialize them.
  514.     *
  515.     * @serialData Null terminated sequence of 0 or more pairs.
  516.     *             The pair consists of a String and Object.
  517.     *             The String indicates the type of object and
  518.     *             is one of the following :
  519.     *             itemListenerK indicating and ItemListener object.
  520.     *
  521.     * @see AWTEventMulticaster.save(ObjectOutputStream, String, EventListener)
  522.     * @see java.awt.Component.itemListenerK
  523.     */
  524.     private void writeObject(ObjectOutputStream s)
  525.       throws java.io.IOException
  526.     {
  527.       s.defaultWriteObject();
  528.  
  529.       AWTEventMulticaster.save(s, itemListenerK, itemListener);
  530.       s.writeObject(null);
  531.     }
  532.  
  533.     /*
  534.     * Read the ObjectInputStream and if it isnt null
  535.     * add a listener to receive item events fired
  536.     * by the Choice item.
  537.     * Unrecognised keys or values will be Ignored.
  538.     * @serial
  539.     * @see removeActionListener()
  540.     * @see addActionListener()
  541.     */
  542.     private void readObject(ObjectInputStream s)
  543.       throws ClassNotFoundException, IOException
  544.     {
  545.       s.defaultReadObject();
  546.  
  547.       Object keyOrNull;
  548.       while(null != (keyOrNull = s.readObject())) {
  549.     String key = ((String)keyOrNull).intern();
  550.  
  551.     if (itemListenerK == key)
  552.       addItemListener((ItemListener)(s.readObject()));
  553.  
  554.     else // skip value for unrecognized key
  555.       s.readObject();
  556.       }
  557.     }
  558.  
  559. }
  560.