Source for javax.swing.JToggleButton

   1: /* JToggleButton.java -- 
   2:    Copyright (C) 2002, 2004, 2005  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.event.ActionEvent;
  42: import java.awt.event.ItemEvent;
  43: import java.awt.event.ItemListener;
  44: 
  45: import javax.accessibility.Accessible;
  46: import javax.accessibility.AccessibleContext;
  47: import javax.accessibility.AccessibleRole;
  48: import javax.accessibility.AccessibleState;
  49: import javax.swing.plaf.ButtonUI;
  50: 
  51: /**
  52:  * The <code>JToggleButton</code> component provides a stateful button,
  53:  * which can be either selected or unselected.  This provides the basis
  54:  * for the implementations of radio buttons (<code>JRadioButton</code>)
  55:  * and check boxes (<code>JCheckBox</code>).
  56:  *
  57:  * @author Michael Koch  (konqueror@gmx.de)
  58:  * @author Graydon Hoare  (graydon@redhat.com)
  59:  * @author Andrew John Hughes  (gnu_andrew@member.fsf.org)
  60:  * @see JRadioButton
  61:  * @see JCheckBox
  62:  * @since 1.2
  63:  */
  64: public class JToggleButton extends AbstractButton implements Accessible
  65: {
  66:   /**
  67:    * This class provides accessibility support for the toggle button.
  68:    */
  69:   protected class AccessibleJToggleButton
  70:     extends AccessibleAbstractButton
  71:     implements ItemListener
  72:   {
  73:     private static final long serialVersionUID = -8652952712161229225L;
  74: 
  75:     /**
  76:      * Constructor for the accessible toggle button.
  77:      */
  78:     public AccessibleJToggleButton()
  79:     {
  80:       super();
  81:       /* Register the accessible toggle button as a listener for item events */
  82:       addItemListener(this);
  83:     }
  84: 
  85:     /**
  86:      * Returns the accessible role for the toggle button.
  87:      *
  88:      * @return An instance of <code>AccessibleRole</code>, describing
  89:      *         the role of the toggle button.
  90:      */
  91:     public AccessibleRole getAccessibleRole()
  92:     {
  93:       return AccessibleRole.TOGGLE_BUTTON;
  94:     }
  95:     
  96:     /**
  97:      * Monitors the toggle button for state changes and fires accessible
  98:      * property change events when they occur.
  99:      *
 100:      * @param event the event that occurred.
 101:      */
 102:     public void itemStateChanged(ItemEvent event)
 103:     {
 104:         /* Fire a state property change event as the button's state has changed */
 105:         if (event.getStateChange() == ItemEvent.SELECTED)
 106:           {
 107:             /* State has changed from unselected (null) to selected */
 108:             firePropertyChange(ACCESSIBLE_STATE_PROPERTY, null, AccessibleState.SELECTED);
 109:           } 
 110:         else
 111:           {
 112:             /* State has changed from selected to unselected (null) */
 113:             firePropertyChange(ACCESSIBLE_STATE_PROPERTY, AccessibleState.ENABLED, null);
 114:           }
 115:     }
 116:     
 117:   }
 118: 
 119:   /**
 120:    * The model handles the storage and maintenance of the state of
 121:    * the toggle button.  This follows the same paradigm (the MVC
 122:    * or Model-View-Controller design pattern) employed by
 123:    * other Swing components, where the data associated with a component
 124:    * is stored separately from the display aspects.
 125:    */
 126:   public static class ToggleButtonModel extends DefaultButtonModel
 127:   {
 128:     /**
 129:      * Compatible with Sun's JDK.
 130:      */
 131:     private static final long serialVersionUID = -1589950750899943974L;
 132:   
 133:     /**
 134:      * Sets the pressed state of the button.  The selected state
 135:      * of the button also changes follwing the button being pressed.
 136:      *
 137:      * @param p true if the button is pressed down.
 138:      */
 139:     public void setPressed(boolean p)  
 140:     {
 141:       // cannot change PRESSED state unless button is enabled
 142:       if (! isEnabled())
 143:         return;
 144:       
 145:       // if this call does not represent a CHANGE in state, then return
 146:       if ((p && isPressed()) || (!p && !isPressed()))
 147:         return;
 148: 
 149:       // The JDK first fires events in the following order:
 150:       // 1. ChangeEvent for selected
 151:       // 2. ChangeEvent for pressed
 152:       // 3. ActionEvent
 153:       // So do we.
 154: 
 155:       // setPressed(false) == mouse release on us,
 156:       // if we were armed, we flip the selected state.
 157:       if (!p && isArmed())
 158:         {
 159:           setSelected(! isSelected());
 160:         }
 161: 
 162:       // make the change
 163:       if (p)
 164:         stateMask = stateMask | PRESSED;
 165:       else
 166:         stateMask = stateMask & (~PRESSED);
 167:       
 168:       // notify interested ChangeListeners
 169:       fireStateChanged();
 170: 
 171:       if (!p && isArmed())
 172:         {
 173:           fireActionPerformed(new ActionEvent(this,
 174:                                               ActionEvent.ACTION_PERFORMED,
 175:                                               actionCommand));
 176:         }
 177: 
 178:     }
 179:   }
 180: 
 181:   /**
 182:    * Compatible with Sun's JDK.
 183:    */
 184:   private static final long serialVersionUID = -3128248873429850443L;
 185:     
 186:   /**
 187:    * Constructs an unselected toggle button with no text or icon.
 188:    */ 
 189:   public JToggleButton()
 190:   {
 191:     this(null, null, false);
 192:   }
 193: 
 194:   /**
 195:    * Constructs a toggle button using the labelling, state
 196:    * and icon specified by the supplied action.
 197:    *
 198:    * @param a the action to use to define the properties of the button.
 199:    */
 200:   public JToggleButton(Action a)
 201:   {
 202:     this();
 203:     setAction(a);
 204:   }
 205: 
 206:   /**
 207:    * Constructs an unselected toggle button with the supplied icon
 208:    * and no text.
 209:    *
 210:    * @param icon the icon to use.
 211:    */
 212:   public JToggleButton(Icon icon)
 213:   { 
 214:     this(null, icon, false);
 215:   }    
 216:   
 217:   /**
 218:    * Constructs a toggle button with the supplied icon and state.
 219:    *
 220:    * @param icon the icon to use.
 221:    * @param selected if true, the toggle button is initially in the
 222:    *        selected state.  Otherwise, the button is unselected.
 223:    */
 224:   public JToggleButton(Icon icon, boolean selected) 
 225:   {
 226:     this(null, icon, selected);
 227:   }
 228:   
 229:   /**
 230:    * Constructs an unselected toggle button using the supplied text
 231:    * and no icon.
 232:    *
 233:    * @param text the text to use.
 234:    */ 
 235:   public JToggleButton(String text)
 236:   {
 237:     this(text, null, false);
 238:   }
 239:       
 240:   /**
 241:    * Constructs a toggle button with the supplied text and state.
 242:    *
 243:    * @param text the text to use.
 244:    * @param selected if true, the toggle button is initially in the
 245:    *        selected state.  Otherwise, the button is unselected.
 246:    */
 247:   public JToggleButton(String text, boolean selected)
 248:   {
 249:     this(text, null, selected);
 250:   }
 251: 
 252:   /**
 253:    * Constructs an unselected toggle button with the supplied text
 254:    * and icon.
 255:    *
 256:    * @param text the text to use.
 257:    * @param icon the icon to use.
 258:    */
 259:   public JToggleButton(String text, Icon icon)
 260:   {
 261:     this(text, icon, false);
 262:   }
 263: 
 264:   /**
 265:    * Constructs a toggle button with the supplied text, icon and state.
 266:    *
 267:    * @param text the text to use.
 268:    * @param icon the icon to use.
 269:    * @param selected if true, the toggle button is initially in the
 270:    *        selected state.  Otherwise, the button is unselected.
 271:    */
 272:   public JToggleButton (String text, Icon icon, boolean selected) 
 273:   {
 274:     super();
 275:     init(text, icon);
 276: 
 277:     setModel(new ToggleButtonModel());    
 278:     model.setSelected(selected);
 279:   }
 280: 
 281:   /**
 282:    * Gets the AccessibleContext associated with this <code>JToggleButton</code>.
 283:    * The context is created, if necessary.
 284:    *
 285:    * @return the associated context
 286:    */
 287:   public AccessibleContext getAccessibleContext()
 288:   {
 289:     /* Create the context if this is the first request */
 290:     if (accessibleContext == null)
 291:       {
 292:         /* Create the context */
 293:     accessibleContext = new AccessibleJToggleButton();
 294:       }
 295:     return accessibleContext;
 296:   }
 297:   
 298:   /**
 299:    * Returns a string that specifies the name of the Look and Feel
 300:    * class that renders this component.
 301:    *
 302:    * @return The Look and Feel UI class in <code>String</code> form.
 303:    */
 304:   public String getUIClassID()
 305:   {
 306:     return "ToggleButtonUI";
 307:   }
 308:   
 309:   /**
 310:    * Returns a textual representation of this component for debugging.
 311:    * Users should not depend on anything as regards the content or formatting
 312:    * of this string, except for the fact that the returned string may never be
 313:    * null (only empty).
 314:    *
 315:    * @return the component in <code>String</code> form for debugging.
 316:    */
 317:   protected  String paramString()
 318:   {
 319:     return super.paramString();
 320:   }
 321:   
 322:   /**
 323:    * This method resets the toggle button's UI delegate to the default UI for
 324:    * the current look and feel.
 325:    */
 326:   public void updateUI()
 327:   {    
 328:     setUI((ButtonUI)UIManager.getUI(this));
 329:   }
 330: 
 331: }
 332: 
 333: