Home » openjdk-7 » java » awt » [javadoc | source]

    1   /*
    2    * Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Oracle designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Oracle in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   22    * or visit www.oracle.com if you need additional information or have any
   23    * questions.
   24    */
   25   
   26   package java.awt;
   27   
   28   import java.awt.peer.ButtonPeer;
   29   import java.util.EventListener;
   30   import java.awt.event;
   31   import java.io.ObjectOutputStream;
   32   import java.io.ObjectInputStream;
   33   import java.io.IOException;
   34   import javax.accessibility;
   35   
   36   /**
   37    * This class creates a labeled button. The application can cause
   38    * some action to happen when the button is pushed. This image
   39    * depicts three views of a "<code>Quit</code>" button as it appears
   40    * under the Solaris operating system:
   41    * <p>
   42    * <img src="doc-files/Button-1.gif" alt="The following context describes the graphic"
   43    * ALIGN=center HSPACE=10 VSPACE=7>
   44    * <p>
   45    * The first view shows the button as it appears normally.
   46    * The second view shows the button
   47    * when it has input focus. Its outline is darkened to let the
   48    * user know that it is an active object. The third view shows the
   49    * button when the user clicks the mouse over the button, and thus
   50    * requests that an action be performed.
   51    * <p>
   52    * The gesture of clicking on a button with the mouse
   53    * is associated with one instance of <code>ActionEvent</code>,
   54    * which is sent out when the mouse is both pressed and released
   55    * over the button. If an application is interested in knowing
   56    * when the button has been pressed but not released, as a separate
   57    * gesture, it can specialize <code>processMouseEvent</code>,
   58    * or it can register itself as a listener for mouse events by
   59    * calling <code>addMouseListener</code>. Both of these methods are
   60    * defined by <code>Component</code>, the abstract superclass of
   61    * all components.
   62    * <p>
   63    * When a button is pressed and released, AWT sends an instance
   64    * of <code>ActionEvent</code> to the button, by calling
   65    * <code>processEvent</code> on the button. The button's
   66    * <code>processEvent</code> method receives all events
   67    * for the button; it passes an action event along by
   68    * calling its own <code>processActionEvent</code> method.
   69    * The latter method passes the action event on to any action
   70    * listeners that have registered an interest in action
   71    * events generated by this button.
   72    * <p>
   73    * If an application wants to perform some action based on
   74    * a button being pressed and released, it should implement
   75    * <code>ActionListener</code> and register the new listener
   76    * to receive events from this button, by calling the button's
   77    * <code>addActionListener</code> method. The application can
   78    * make use of the button's action command as a messaging protocol.
   79    *
   80    * @author      Sami Shaio
   81    * @see         java.awt.event.ActionEvent
   82    * @see         java.awt.event.ActionListener
   83    * @see         java.awt.Component#processMouseEvent
   84    * @see         java.awt.Component#addMouseListener
   85    * @since       JDK1.0
   86    */
   87   public class Button extends Component implements Accessible {
   88   
   89       /**
   90        * The button's label.  This value may be null.
   91        * @serial
   92        * @see #getLabel()
   93        * @see #setLabel(String)
   94        */
   95       String label;
   96   
   97       /**
   98        * The action to be performed once a button has been
   99        * pressed.  This value may be null.
  100        * @serial
  101        * @see #getActionCommand()
  102        * @see #setActionCommand(String)
  103        */
  104       String actionCommand;
  105   
  106       transient ActionListener actionListener;
  107   
  108       private static final String base = "button";
  109       private static int nameCounter = 0;
  110   
  111       /*
  112        * JDK 1.1 serialVersionUID
  113        */
  114       private static final long serialVersionUID = -8774683716313001058L;
  115   
  116   
  117       static {
  118           /* ensure that the necessary native libraries are loaded */
  119           Toolkit.loadLibraries();
  120           if (!GraphicsEnvironment.isHeadless()) {
  121               initIDs();
  122           }
  123       }
  124   
  125       /**
  126        * Initialize JNI field and method IDs for fields that may be
  127        * accessed from C.
  128        */
  129       private static native void initIDs();
  130   
  131       /**
  132        * Constructs a button with an empty string for its label.
  133        *
  134        * @exception HeadlessException if GraphicsEnvironment.isHeadless()
  135        * returns true
  136        * @see java.awt.GraphicsEnvironment#isHeadless
  137        */
  138       public Button() throws HeadlessException {
  139           this("");
  140       }
  141   
  142       /**
  143        * Constructs a button with the specified label.
  144        *
  145        * @param label  a string label for the button, or
  146        *               <code>null</code> for no label
  147        * @exception HeadlessException if GraphicsEnvironment.isHeadless()
  148        * returns true
  149        * @see java.awt.GraphicsEnvironment#isHeadless
  150        */
  151       public Button(String label) throws HeadlessException {
  152           GraphicsEnvironment.checkHeadless();
  153           this.label = label;
  154       }
  155   
  156       /**
  157        * Construct a name for this component.  Called by getName() when the
  158        * name is null.
  159        */
  160       String constructComponentName() {
  161           synchronized (Button.class) {
  162               return base + nameCounter++;
  163           }
  164       }
  165   
  166       /**
  167        * Creates the peer of the button.  The button's peer allows the
  168        * application to change the look of the button without changing
  169        * its functionality.
  170        *
  171        * @see     java.awt.Toolkit#createButton(java.awt.Button)
  172        * @see     java.awt.Component#getToolkit()
  173        */
  174       public void addNotify() {
  175           synchronized(getTreeLock()) {
  176               if (peer == null)
  177                   peer = getToolkit().createButton(this);
  178               super.addNotify();
  179           }
  180       }
  181   
  182       /**
  183        * Gets the label of this button.
  184        *
  185        * @return    the button's label, or <code>null</code>
  186        *                if the button has no label.
  187        * @see       java.awt.Button#setLabel
  188        */
  189       public String getLabel() {
  190           return label;
  191       }
  192   
  193       /**
  194        * Sets the button's label to be the specified string.
  195        *
  196        * @param     label   the new label, or <code>null</code>
  197        *                if the button has no label.
  198        * @see       java.awt.Button#getLabel
  199        */
  200       public void setLabel(String label) {
  201           boolean testvalid = false;
  202   
  203           synchronized (this) {
  204               if (label != this.label && (this.label == null ||
  205                                           !this.label.equals(label))) {
  206                   this.label = label;
  207                   ButtonPeer peer = (ButtonPeer)this.peer;
  208                   if (peer != null) {
  209                       peer.setLabel(label);
  210                   }
  211                   testvalid = true;
  212               }
  213           }
  214   
  215           // This could change the preferred size of the Component.
  216           if (testvalid) {
  217               invalidateIfValid();
  218           }
  219       }
  220   
  221       /**
  222        * Sets the command name for the action event fired
  223        * by this button. By default this action command is
  224        * set to match the label of the button.
  225        *
  226        * @param     command  a string used to set the button's
  227        *                  action command.
  228        *            If the string is <code>null</code> then the action command
  229        *            is set to match the label of the button.
  230        * @see       java.awt.event.ActionEvent
  231        * @since     JDK1.1
  232        */
  233       public void setActionCommand(String command) {
  234           actionCommand = command;
  235       }
  236   
  237       /**
  238        * Returns the command name of the action event fired by this button.
  239        * If the command name is <code>null</code> (default) then this method
  240        * returns the label of the button.
  241        */
  242       public String getActionCommand() {
  243           return (actionCommand == null? label : actionCommand);
  244       }
  245   
  246       /**
  247        * Adds the specified action listener to receive action events from
  248        * this button. Action events occur when a user presses or releases
  249        * the mouse over this button.
  250        * If l is null, no exception is thrown and no action is performed.
  251        * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
  252        * >AWT Threading Issues</a> for details on AWT's threading model.
  253        *
  254        * @param         l the action listener
  255        * @see           #removeActionListener
  256        * @see           #getActionListeners
  257        * @see           java.awt.event.ActionListener
  258        * @since         JDK1.1
  259        */
  260       public synchronized void addActionListener(ActionListener l) {
  261           if (l == null) {
  262               return;
  263           }
  264           actionListener = AWTEventMulticaster.add(actionListener, l);
  265           newEventsOnly = true;
  266       }
  267   
  268       /**
  269        * Removes the specified action listener so that it no longer
  270        * receives action events from this button. Action events occur
  271        * when a user presses or releases the mouse over this button.
  272        * If l is null, no exception is thrown and no action is performed.
  273        * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
  274        * >AWT Threading Issues</a> for details on AWT's threading model.
  275        *
  276        * @param           l     the action listener
  277        * @see             #addActionListener
  278        * @see             #getActionListeners
  279        * @see             java.awt.event.ActionListener
  280        * @since           JDK1.1
  281        */
  282       public synchronized void removeActionListener(ActionListener l) {
  283           if (l == null) {
  284               return;
  285           }
  286           actionListener = AWTEventMulticaster.remove(actionListener, l);
  287       }
  288   
  289       /**
  290        * Returns an array of all the action listeners
  291        * registered on this button.
  292        *
  293        * @return all of this button's <code>ActionListener</code>s
  294        *         or an empty array if no action
  295        *         listeners are currently registered
  296        *
  297        * @see             #addActionListener
  298        * @see             #removeActionListener
  299        * @see             java.awt.event.ActionListener
  300        * @since 1.4
  301        */
  302       public synchronized ActionListener[] getActionListeners() {
  303           return (ActionListener[]) (getListeners(ActionListener.class));
  304       }
  305   
  306       /**
  307        * Returns an array of all the objects currently registered
  308        * as <code><em>Foo</em>Listener</code>s
  309        * upon this <code>Button</code>.
  310        * <code><em>Foo</em>Listener</code>s are registered using the
  311        * <code>add<em>Foo</em>Listener</code> method.
  312        *
  313        * <p>
  314        * You can specify the <code>listenerType</code> argument
  315        * with a class literal, such as
  316        * <code><em>Foo</em>Listener.class</code>.
  317        * For example, you can query a
  318        * <code>Button</code> <code>b</code>
  319        * for its action listeners with the following code:
  320        *
  321        * <pre>ActionListener[] als = (ActionListener[])(b.getListeners(ActionListener.class));</pre>
  322        *
  323        * If no such listeners exist, this method returns an empty array.
  324        *
  325        * @param listenerType the type of listeners requested; this parameter
  326        *          should specify an interface that descends from
  327        *          <code>java.util.EventListener</code>
  328        * @return an array of all objects registered as
  329        *          <code><em>Foo</em>Listener</code>s on this button,
  330        *          or an empty array if no such
  331        *          listeners have been added
  332        * @exception ClassCastException if <code>listenerType</code>
  333        *          doesn't specify a class or interface that implements
  334        *          <code>java.util.EventListener</code>
  335        *
  336        * @see #getActionListeners
  337        * @since 1.3
  338        */
  339       public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
  340           EventListener l = null;
  341           if  (listenerType == ActionListener.class) {
  342               l = actionListener;
  343           } else {
  344               return super.getListeners(listenerType);
  345           }
  346           return AWTEventMulticaster.getListeners(l, listenerType);
  347       }
  348   
  349       // REMIND: remove when filtering is done at lower level
  350       boolean eventEnabled(AWTEvent e) {
  351           if (e.id == ActionEvent.ACTION_PERFORMED) {
  352               if ((eventMask & AWTEvent.ACTION_EVENT_MASK) != 0 ||
  353                   actionListener != null) {
  354                   return true;
  355               }
  356               return false;
  357           }
  358           return super.eventEnabled(e);
  359       }
  360   
  361       /**
  362        * Processes events on this button. If an event is
  363        * an instance of <code>ActionEvent</code>, this method invokes
  364        * the <code>processActionEvent</code> method. Otherwise,
  365        * it invokes <code>processEvent</code> on the superclass.
  366        * <p>Note that if the event parameter is <code>null</code>
  367        * the behavior is unspecified and may result in an
  368        * exception.
  369        *
  370        * @param        e the event
  371        * @see          java.awt.event.ActionEvent
  372        * @see          java.awt.Button#processActionEvent
  373        * @since        JDK1.1
  374        */
  375       protected void processEvent(AWTEvent e) {
  376           if (e instanceof ActionEvent) {
  377               processActionEvent((ActionEvent)e);
  378               return;
  379           }
  380           super.processEvent(e);
  381       }
  382   
  383       /**
  384        * Processes action events occurring on this button
  385        * by dispatching them to any registered
  386        * <code>ActionListener</code> objects.
  387        * <p>
  388        * This method is not called unless action events are
  389        * enabled for this button. Action events are enabled
  390        * when one of the following occurs:
  391        * <p><ul>
  392        * <li>An <code>ActionListener</code> object is registered
  393        * via <code>addActionListener</code>.
  394        * <li>Action events are enabled via <code>enableEvents</code>.
  395        * </ul>
  396        * <p>Note that if the event parameter is <code>null</code>
  397        * the behavior is unspecified and may result in an
  398        * exception.
  399        *
  400        * @param       e the action event
  401        * @see         java.awt.event.ActionListener
  402        * @see         java.awt.Button#addActionListener
  403        * @see         java.awt.Component#enableEvents
  404        * @since       JDK1.1
  405        */
  406       protected void processActionEvent(ActionEvent e) {
  407           ActionListener listener = actionListener;
  408           if (listener != null) {
  409               listener.actionPerformed(e);
  410           }
  411       }
  412   
  413       /**
  414        * Returns a string representing the state of this <code>Button</code>.
  415        * This method is intended to be used only for debugging purposes, and the
  416        * content and format of the returned string may vary between
  417        * implementations. The returned string may be empty but may not be
  418        * <code>null</code>.
  419        *
  420        * @return     the parameter string of this button
  421        */
  422       protected String paramString() {
  423           return super.paramString() + ",label=" + label;
  424       }
  425   
  426   
  427       /* Serialization support.
  428        */
  429   
  430       /*
  431        * Button Serial Data Version.
  432        * @serial
  433        */
  434       private int buttonSerializedDataVersion = 1;
  435   
  436       /**
  437        * Writes default serializable fields to stream.  Writes
  438        * a list of serializable <code>ActionListeners</code>
  439        * as optional data.  The non-serializable
  440        * <code>ActionListeners</code> are detected and
  441        * no attempt is made to serialize them.
  442        *
  443        * @serialData <code>null</code> terminated sequence of 0 or
  444        *   more pairs: the pair consists of a <code>String</code>
  445        *   and an <code>Object</code>; the <code>String</code>
  446        *   indicates the type of object and is one of the following:
  447        *   <code>actionListenerK</code> indicating an
  448        *     <code>ActionListener</code> object
  449        *
  450        * @param s the <code>ObjectOutputStream</code> to write
  451        * @see AWTEventMulticaster#save(ObjectOutputStream, String, EventListener)
  452        * @see java.awt.Component#actionListenerK
  453        * @see #readObject(ObjectInputStream)
  454        */
  455       private void writeObject(ObjectOutputStream s)
  456         throws IOException
  457       {
  458         s.defaultWriteObject();
  459   
  460         AWTEventMulticaster.save(s, actionListenerK, actionListener);
  461         s.writeObject(null);
  462       }
  463   
  464       /**
  465        * Reads the <code>ObjectInputStream</code> and if
  466        * it isn't <code>null</code> adds a listener to
  467        * receive action events fired by the button.
  468        * Unrecognized keys or values will be ignored.
  469        *
  470        * @param s the <code>ObjectInputStream</code> to read
  471        * @exception HeadlessException if
  472        *   <code>GraphicsEnvironment.isHeadless</code> returns
  473        *   <code>true</code>
  474        * @serial
  475        * @see #removeActionListener(ActionListener)
  476        * @see #addActionListener(ActionListener)
  477        * @see java.awt.GraphicsEnvironment#isHeadless
  478        * @see #writeObject(ObjectOutputStream)
  479        */
  480       private void readObject(ObjectInputStream s)
  481         throws ClassNotFoundException, IOException, HeadlessException
  482       {
  483         GraphicsEnvironment.checkHeadless();
  484         s.defaultReadObject();
  485   
  486         Object keyOrNull;
  487         while(null != (keyOrNull = s.readObject())) {
  488           String key = ((String)keyOrNull).intern();
  489   
  490           if (actionListenerK == key)
  491             addActionListener((ActionListener)(s.readObject()));
  492   
  493           else // skip value for unrecognized key
  494             s.readObject();
  495         }
  496       }
  497   
  498   
  499   /////////////////
  500   // Accessibility support
  501   ////////////////
  502   
  503       /**
  504        * Gets the <code>AccessibleContext</code> associated with
  505        * this <code>Button</code>. For buttons, the
  506        * <code>AccessibleContext</code> takes the form of an
  507        * <code>AccessibleAWTButton</code>.
  508        * A new <code>AccessibleAWTButton</code> instance is
  509        * created if necessary.
  510        *
  511        * @return an <code>AccessibleAWTButton</code> that serves as the
  512        *         <code>AccessibleContext</code> of this <code>Button</code>
  513        * @beaninfo
  514        *       expert: true
  515        *  description: The AccessibleContext associated with this Button.
  516        * @since 1.3
  517        */
  518       public AccessibleContext getAccessibleContext() {
  519           if (accessibleContext == null) {
  520               accessibleContext = new AccessibleAWTButton();
  521           }
  522           return accessibleContext;
  523       }
  524   
  525       /**
  526        * This class implements accessibility support for the
  527        * <code>Button</code> class.  It provides an implementation of the
  528        * Java Accessibility API appropriate to button user-interface elements.
  529        * @since 1.3
  530        */
  531       protected class AccessibleAWTButton extends AccessibleAWTComponent
  532           implements AccessibleAction, AccessibleValue
  533       {
  534           /*
  535            * JDK 1.3 serialVersionUID
  536            */
  537           private static final long serialVersionUID = -5932203980244017102L;
  538   
  539           /**
  540            * Get the accessible name of this object.
  541            *
  542            * @return the localized name of the object -- can be null if this
  543            * object does not have a name
  544            */
  545           public String getAccessibleName() {
  546               if (accessibleName != null) {
  547                   return accessibleName;
  548               } else {
  549                   if (getLabel() == null) {
  550                       return super.getAccessibleName();
  551                   } else {
  552                       return getLabel();
  553                   }
  554               }
  555           }
  556   
  557           /**
  558            * Get the AccessibleAction associated with this object.  In the
  559            * implementation of the Java Accessibility API for this class,
  560            * return this object, which is responsible for implementing the
  561            * AccessibleAction interface on behalf of itself.
  562            *
  563            * @return this object
  564            */
  565           public AccessibleAction getAccessibleAction() {
  566               return this;
  567           }
  568   
  569           /**
  570            * Get the AccessibleValue associated with this object.  In the
  571            * implementation of the Java Accessibility API for this class,
  572            * return this object, which is responsible for implementing the
  573            * AccessibleValue interface on behalf of itself.
  574            *
  575            * @return this object
  576            */
  577           public AccessibleValue getAccessibleValue() {
  578               return this;
  579           }
  580   
  581           /**
  582            * Returns the number of Actions available in this object.  The
  583            * default behavior of a button is to have one action - toggle
  584            * the button.
  585            *
  586            * @return 1, the number of Actions in this object
  587            */
  588           public int getAccessibleActionCount() {
  589               return 1;
  590           }
  591   
  592           /**
  593            * Return a description of the specified action of the object.
  594            *
  595            * @param i zero-based index of the actions
  596            */
  597           public String getAccessibleActionDescription(int i) {
  598               if (i == 0) {
  599                   // [[[PENDING:  WDW -- need to provide a localized string]]]
  600                   return "click";
  601               } else {
  602                   return null;
  603               }
  604           }
  605   
  606           /**
  607            * Perform the specified Action on the object
  608            *
  609            * @param i zero-based index of actions
  610            * @return true if the the action was performed; else false.
  611            */
  612           public boolean doAccessibleAction(int i) {
  613               if (i == 0) {
  614                   // Simulate a button click
  615                   Toolkit.getEventQueue().postEvent(
  616                           new ActionEvent(Button.this,
  617                                           ActionEvent.ACTION_PERFORMED,
  618                                           Button.this.getActionCommand()));
  619                   return true;
  620               } else {
  621                   return false;
  622               }
  623           }
  624   
  625           /**
  626            * Get the value of this object as a Number.
  627            *
  628            * @return An Integer of 0 if this isn't selected or an Integer of 1 if
  629            * this is selected.
  630            * @see javax.swing.AbstractButton#isSelected()
  631            */
  632           public Number getCurrentAccessibleValue() {
  633               return Integer.valueOf(0);
  634           }
  635   
  636           /**
  637            * Set the value of this object as a Number.
  638            *
  639            * @return True if the value was set.
  640            */
  641           public boolean setCurrentAccessibleValue(Number n) {
  642               return false;
  643           }
  644   
  645           /**
  646            * Get the minimum value of this object as a Number.
  647            *
  648            * @return An Integer of 0.
  649            */
  650           public Number getMinimumAccessibleValue() {
  651               return Integer.valueOf(0);
  652           }
  653   
  654           /**
  655            * Get the maximum value of this object as a Number.
  656            *
  657            * @return An Integer of 0.
  658            */
  659           public Number getMaximumAccessibleValue() {
  660               return Integer.valueOf(0);
  661           }
  662   
  663           /**
  664            * Get the role of this object.
  665            *
  666            * @return an instance of AccessibleRole describing the role of the
  667            * object
  668            * @see AccessibleRole
  669            */
  670           public AccessibleRole getAccessibleRole() {
  671               return AccessibleRole.PUSH_BUTTON;
  672           }
  673       } // inner class AccessibleAWTButton
  674   
  675   }

Home » openjdk-7 » java » awt » [javadoc | source]