Save This Page
Home » openjdk-7 » javax » swing » [javadoc | source]
    1   /* DefaultButtonModel.java --
    2      Copyright (C) 2002, 2004 Free Software Foundation, Inc.
    3   
    4   This file is part of GNU Classpath.
    5   
    6   GNU Classpath is free software; you can redistribute it and/or modify
    7   it under the terms of the GNU General Public License as published by
    8   the Free Software Foundation; either version 2, or (at your option)
    9   any later version.
   10   
   11   GNU Classpath is distributed in the hope that it will be useful, but
   12   WITHOUT ANY WARRANTY; without even the implied warranty of
   13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   14   General Public License for more details.
   15   
   16   You should have received a copy of the GNU General Public License
   17   along with GNU Classpath; see the file COPYING.  If not, write to the
   18   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
   19   02110-1301 USA.
   20   
   21   Linking this library statically or dynamically with other modules is
   22   making a combined work based on this library.  Thus, the terms and
   23   conditions of the GNU General Public License cover the whole
   24   combination.
   25   
   26   As a special exception, the copyright holders of this library give you
   27   permission to link this library with independent modules to produce an
   28   executable, regardless of the license terms of these independent
   29   modules, and to copy and distribute the resulting executable under
   30   terms of your choice, provided that you also meet, for each linked
   31   independent module, the terms and conditions of the license of that
   32   module.  An independent module is a module which is not derived from
   33   or based on this library.  If you modify this library, you may extend
   34   this exception to your version of the library, but you are not
   35   obligated to do so.  If you do not wish to do so, delete this
   36   exception statement from your version. */
   37   
   38   
   39   package javax.swing;
   40   
   41   import java.awt.ItemSelectable;
   42   import java.awt.event.ActionEvent;
   43   import java.awt.event.ActionListener;
   44   import java.awt.event.ItemEvent;
   45   import java.awt.event.ItemListener;
   46   import java.awt.event.KeyEvent;
   47   import java.io.Serializable;
   48   import java.util.EventListener;
   49   
   50   import javax.swing.event.ChangeEvent;
   51   import javax.swing.event.ChangeListener;
   52   import javax.swing.event.EventListenerList;
   53   
   54   /**
   55    * The default implementation of {@link ButtonModel}.
   56    * The purpose of this class is to model the dynamic state of an abstract
   57    * button. The concrete button type holding this state may be a a "toggle"
   58    * button (checkbox, radio button) or a "push" button (menu button, button).
   59    * If the model is disabled, only the "selected" property can be changed. An
   60    * attempt to change the "armed", "rollover" or "pressed" properties  while
   61    * the model is disabled will be blocked. Any successful (non-blocked) change
   62    * to the model's properties will trigger the firing of a ChangeEvent. Any
   63    * change to the "selected" property will trigger the firing of an ItemEvent
   64    * in addition to ChangeEvent. This is true whether the model is enabled or
   65    * not. One other state change is special: the transition from "enabled,
   66    * armed and pressd" to "enabled, armed and not-pressed". This is considered
   67    * the "trailing edge" of a successful mouse click, and therefore fires an
   68    * ActionEvent in addition to a ChangeEvent. In all other respects this class
   69    * is just a container of boolean flags.
   70    *
   71    * @author Graydon Hoare (graydon_at_redhat.com)
   72    */
   73   public class DefaultButtonModel implements ButtonModel, Serializable
   74   {
   75     /** DOCUMENT ME! */
   76     private static final long serialVersionUID = -5342609566534980231L;
   77   
   78     /**
   79      * Indicates that the button is <em>partially</em> committed to being
   80      * pressed, but not entirely. This usually happens when a user has pressed
   81      * but not yet released the mouse button.
   82      */
   83     public static final int ARMED = 1;
   84   
   85     /**
   86      * State constant indicating that the button is enabled. Buttons cannot be
   87      * pressed or selected unless they are enabled.
   88      */
   89     public static final int ENABLED = 8;
   90   
   91     /**
   92      * State constant indicating that the user is holding down the button. When
   93      * this transitions from true to false, an ActionEvent may be fired,
   94      * depending on the value of the "armed" property.
   95      */
   96     public static final int PRESSED = 4;
   97   
   98     /**
   99      * State constant indicating that the mouse is currently positioned over the
  100      * button.
  101      */
  102     public static final int ROLLOVER = 16;
  103   
  104     /**
  105      * State constant indicating that the button is selected. This constant is
  106      * only meaningful for toggle-type buttons (radio buttons, checkboxes).
  107      */
  108     public static final int SELECTED = 2;
  109   
  110     /**
  111      * Represents the "state properties" (armed, enabled, pressed, rollover and
  112      * selected) by a bitwise combination of integer constants.
  113      */
  114     protected int stateMask = ENABLED;
  115   
  116     /**
  117      * List of ItemListeners, ChangeListeners, and ActionListeners registered on
  118      * this model.
  119      */
  120     protected EventListenerList listenerList = new EventListenerList();
  121   
  122     /** The single ChangeEvent this model (re)uses to call its ChangeListeners. */
  123     protected ChangeEvent changeEvent = new ChangeEvent(this);
  124   
  125     /**
  126      * The group this model belongs to. Only one button in a group may be
  127      * selected at any given time.
  128      */
  129     protected ButtonGroup group;
  130   
  131     /**
  132      * The key code (one of {@link java.awt.event.KeyEvent} VK_) used to press
  133      * this button via a keyboard interface.
  134      */
  135     protected int mnemonic = KeyEvent.VK_UNDEFINED;
  136   
  137     /**
  138      * The string used as the "command" property of any ActionEvent this model
  139      * sends.
  140      */
  141     protected String actionCommand;
  142   
  143     /**
  144      * Creates a new DefaultButtonModel object.
  145      */
  146     public DefaultButtonModel()
  147     {
  148       // Nothing to do here.
  149     }
  150   
  151     /**
  152      * Return <code>null</code>. Use {@link AbstractButton} if you wish to
  153      * interface with a button via an {@link ItemSelectable} interface.
  154      *
  155      * @return <code>null</code>
  156      */
  157     public Object[] getSelectedObjects()
  158     {
  159       return null;
  160     }
  161   
  162     /**
  163      * Returns a specified class of listeners.
  164      *
  165      * @param listenerType the type of listener to return
  166      *
  167      * @return array of listeners
  168      */
  169     public EventListener[] getListeners(Class listenerType)
  170     {
  171       return listenerList.getListeners(listenerType);
  172     }
  173   
  174     /**
  175      * Add an ActionListener to the model. Usually only called to subscribe an
  176      * AbstractButton's listener to the model.
  177      *
  178      * @param l The listener to add
  179      */
  180     public void addActionListener(ActionListener l)
  181     {
  182       listenerList.add(ActionListener.class, l);
  183     }
  184   
  185     /**
  186      * Remove an ActionListener to the model. Usually only called to unsubscribe
  187      * an AbstractButton's listener to the model.
  188      *
  189      * @param l The listener to remove
  190      */
  191     public void removeActionListener(ActionListener l)
  192     {
  193       listenerList.remove(ActionListener.class, l);
  194     }
  195   
  196     /**
  197      * Returns all registered <code>ActionListener</code> objects.
  198      *
  199      * @return array of <code>ActionListener</code> objects
  200      */
  201     public ActionListener[] getActionListeners()
  202     {
  203       return (ActionListener[]) listenerList.getListeners(ActionListener.class);
  204     }
  205   
  206     /**
  207      * Add an ItemListener to the model. Usually only called to subscribe an
  208      * AbstractButton's listener to the model.
  209      *
  210      * @param l The listener to add
  211      */
  212     public void addItemListener(ItemListener l)
  213     {
  214       listenerList.add(ItemListener.class, l);
  215     }
  216   
  217     /**
  218      * Remove an ItemListener to the model. Usually only called to unsubscribe
  219      * an AbstractButton's listener to the model.
  220      *
  221      * @param l The listener to remove
  222      */
  223     public void removeItemListener(ItemListener l)
  224     {
  225       listenerList.remove(ItemListener.class, l);
  226     }
  227   
  228     /**
  229      * Returns all registered <code>ItemListener</code> objects.
  230      *
  231      * @return array of <code>ItemListener</code> objects
  232      */
  233     public ItemListener[] getItemListeners()
  234     {
  235       return (ItemListener[]) listenerList.getListeners(ItemListener.class);
  236     }
  237   
  238     /**
  239      * Add a ChangeListener to the model. Usually only called to subscribe an
  240      * AbstractButton's listener to the model.
  241      *
  242      * @param l The listener to add
  243      */
  244     public void addChangeListener(ChangeListener l)
  245     {
  246       listenerList.add(ChangeListener.class, l);
  247     }
  248   
  249     /**
  250      * Remove a ChangeListener to the model. Usually only called to unsubscribe
  251      * an AbstractButton's listener to the model.
  252      *
  253      * @param l The listener to remove
  254      */
  255     public void removeChangeListener(ChangeListener l)
  256     {
  257       listenerList.remove(ChangeListener.class, l);
  258     }
  259   
  260     /**
  261      * Returns all registered <code>ChangeListener</code> objects.
  262      *
  263      * @return array of <code>ChangeListener</code> objects
  264      */
  265     public ChangeListener[] getChangeListeners()
  266     {
  267       return (ChangeListener[]) listenerList.getListeners(ChangeListener.class);
  268     }
  269   
  270     /**
  271      * Inform each ItemListener in the {@link #listenerList} that an ItemEvent
  272      * has occurred. This happens in response to any change to the {@link
  273      * #stateMask} field.
  274      *
  275      * @param e The ItemEvent to fire
  276      */
  277     protected void fireItemStateChanged(ItemEvent e)
  278     {
  279       ItemListener[] ll = getItemListeners();
  280   
  281       for (int i = 0; i < ll.length; i++)
  282         ll[i].itemStateChanged(e);
  283     }
  284   
  285     /**
  286      * Inform each ActionListener in the {@link #listenerList} that an
  287      * ActionEvent has occurred. This happens in response to the any change to
  288      * the {@link #stateMask} field which makes the enabled, armed and pressed
  289      * properties all simultaneously <code>true</code>.
  290      *
  291      * @param e The ActionEvent to fire
  292      */
  293     protected void fireActionPerformed(ActionEvent e)
  294     {
  295       ActionListener[] ll = getActionListeners();
  296   
  297       for (int i = 0; i < ll.length; i++)
  298         ll[i].actionPerformed(e);
  299     }
  300   
  301     /**
  302      * Inform each ChangeListener in the {@link #listenerList} that a ChangeEvent
  303      * has occurred. This happens in response to the any change to a property
  304      * of the model.
  305      */
  306     protected void fireStateChanged()
  307     {
  308       ChangeListener[] ll = getChangeListeners();
  309   
  310       for (int i = 0; i < ll.length; i++)
  311         ll[i].stateChanged(changeEvent);
  312     }
  313   
  314     /**
  315      * Get the value of the model's "armed" property.
  316      *
  317      * @return The current "armed" property
  318      */
  319     public boolean isArmed()
  320     {
  321       return (stateMask & ARMED) == ARMED;
  322     }
  323   
  324     /**
  325      * Set the value of the model's "armed" property.
  326      *
  327      * @param a The new "armed" property
  328      */
  329     public void setArmed(boolean a)
  330     {
  331       // if this call does not represent a CHANGE in state, then return
  332       if ((a && isArmed()) || (!a && !isArmed()))
  333         return;
  334       
  335       // cannot change ARMED state unless button is enabled
  336       if (!isEnabled())
  337         return;
  338   
  339       // make the change
  340       if (a)
  341         stateMask = stateMask | ARMED;
  342       else
  343         stateMask = stateMask & (~ARMED);
  344   
  345       // notify interested ChangeListeners
  346       fireStateChanged();
  347     }
  348   
  349     /**
  350      * Get the value of the model's "enabled" property.
  351      *
  352      * @return The current "enabled" property.
  353      */
  354     public boolean isEnabled()
  355     {
  356       return (stateMask & ENABLED) == ENABLED;
  357     }
  358   
  359     /**
  360      * Set the value of the model's "enabled" property.
  361      *
  362      * @param e The new "enabled" property
  363      */
  364     public void setEnabled(boolean e)
  365     {
  366       // if this call does not represent a CHANGE in state, then return
  367       if ((e && isEnabled()) || (!e && !isEnabled()))
  368         return;
  369   
  370       // make the change
  371       if (e)
  372         stateMask = stateMask | ENABLED;
  373       else
  374         stateMask = stateMask & (~ENABLED);
  375   
  376       // notify interested ChangeListeners
  377       fireStateChanged();
  378     }
  379   
  380     /**
  381      * Set the value of the model's "pressed" property.
  382      *
  383      * @param p The new "pressed" property
  384      */
  385     public void setPressed(boolean p)
  386     {
  387       // if this call does not represent a CHANGE in state, then return
  388       if ((p && isPressed()) || (!p && !isPressed()))
  389         return;
  390   
  391       // cannot changed PRESSED state unless button is enabled
  392       if (!isEnabled())
  393         return;
  394   
  395       // make the change
  396       if (p)
  397         stateMask = stateMask | PRESSED;
  398       else
  399         stateMask = stateMask & (~PRESSED);
  400   
  401       // if button is armed and was released, fire action event
  402       if (!p && isArmed())
  403         fireActionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED,
  404                                             actionCommand));
  405   
  406       // notify interested ChangeListeners
  407       fireStateChanged();
  408     }
  409   
  410     /**
  411      * Get the value of the model's "pressed" property.
  412      *
  413      * @return The current "pressed" property
  414      */
  415     public boolean isPressed()
  416     {
  417       return (stateMask & PRESSED) == PRESSED;
  418     }
  419   
  420     /**
  421      * Set the value of the model's "rollover" property.
  422      *
  423      * @param r The new "rollover" property
  424      */
  425     public void setRollover(boolean r)
  426     {
  427       // if this call does not represent a CHANGE in state, then return
  428       if ((r && isRollover()) || (!r && !isRollover()))
  429         return;
  430       
  431       // cannot set ROLLOVER property unless button is enabled
  432       if (!isEnabled())
  433         return;
  434   
  435       // make the change
  436       if (r)
  437         stateMask = stateMask | ROLLOVER;
  438       else
  439         stateMask = stateMask & (~ROLLOVER);
  440   
  441       // notify interested ChangeListeners
  442       fireStateChanged();
  443     }
  444   
  445     /**
  446      * Set the value of the model's "selected" property.
  447      *
  448      * @param s The new "selected" property
  449      */
  450     public void setSelected(boolean s)
  451     {
  452       // if this call does not represent a CHANGE in state, then return
  453       if ((s && isSelected()) || (!s && !isSelected()))
  454         return;
  455       
  456       // make the change
  457       if (s)
  458         stateMask = stateMask | SELECTED;
  459       else
  460         stateMask = stateMask & (~SELECTED);
  461   
  462       // notify interested ChangeListeners
  463       fireStateChanged();
  464   
  465       // fire ItemStateChanged events
  466       if (s)
  467         {
  468           fireItemStateChanged(new ItemEvent(this, ItemEvent.ITEM_STATE_CHANGED,
  469                                              null, ItemEvent.SELECTED));
  470           if (group != null)
  471             group.setSelected(this, true);
  472         }
  473       else
  474         {
  475           fireItemStateChanged(new ItemEvent(this, ItemEvent.ITEM_STATE_CHANGED,
  476                                              null, ItemEvent.DESELECTED));
  477           if (group != null)
  478             group.setSelected(this, false);
  479         }
  480     }
  481   
  482     /**
  483      * Get the value of the model's "selected" property.
  484      *
  485      * @return The current "selected" property
  486      */
  487     public boolean isSelected()
  488     {
  489       return (stateMask & SELECTED) == SELECTED;
  490     }
  491   
  492     /**
  493      * Get the value of the model's "rollover" property.
  494      *
  495      * @return The current "rollover" property
  496      */
  497     public boolean isRollover()
  498     {
  499       return (stateMask & ROLLOVER) == ROLLOVER;
  500     }
  501   
  502     /**
  503      * Get the value of the model's "mnemonic" property.
  504      *
  505      * @return The current "mnemonic" property
  506      */
  507     public int getMnemonic()
  508     {
  509       return mnemonic;
  510     }
  511   
  512     /**
  513      * Set the value of the model's "mnemonic" property.
  514      *
  515      * @param key The new "mnemonic" property
  516      */
  517     public void setMnemonic(int key)
  518     {
  519       if (mnemonic != key)
  520         {
  521           mnemonic = key;
  522           fireStateChanged();
  523         }
  524     }
  525   
  526     /**
  527      * Set the value of the model's "actionCommand" property. This property is
  528      * used as the "command" property of the {@link ActionEvent} fired from the
  529      * model.
  530      *
  531      * @param s The new "actionCommand" property.
  532      */
  533     public void setActionCommand(String s)
  534     {
  535       if (actionCommand != s)
  536         {
  537           actionCommand = s;
  538           fireStateChanged();
  539         }
  540     }
  541   
  542     /**
  543      * Returns the current value of the model's "actionCommand" property.
  544      *
  545      * @return The current "actionCommand" property
  546      */
  547     public String getActionCommand()
  548     {
  549       return actionCommand;
  550     }
  551   
  552     /**
  553      * Set the value of the model's "group" property. The model is said to be a
  554      * member of the {@link ButtonGroup} held in its "group" property, and only
  555      * one model in a given group can have their "selected" property be
  556      * <code>true</code> at a time.
  557      *
  558      * @param g The new "group" property
  559      */
  560     public void setGroup(ButtonGroup g)
  561     {
  562       if (group != g)
  563         {
  564           group = g;
  565           fireStateChanged();
  566         }
  567     }
  568   
  569     /**
  570      * Returns the current value of the model's "group" property.
  571      *
  572      * @return The value of the "group" property
  573      */
  574     public ButtonGroup getGroup()
  575     {
  576       return group;
  577     }
  578   }

Save This Page
Home » openjdk-7 » javax » swing » [javadoc | source]