Source for javax.swing.JToggleButton

   1: /* JToggleButton.java -- 
   2:    Copyright (C) 2002, 2004, 2005, 2006,  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:        * Checks if the button is selected.
 181:        * 
 182:        * @return <code>true</code> if the button is selected.
 183:        */
 184:       public boolean isSelected()
 185:       {
 186:         return super.isSelected();
 187:       }
 188:       
 189:       /**
 190:        * Sets the selected state of the button.
 191:        * 
 192:        * @param b true if button is selected
 193:        */
 194:       public void setSelected(boolean b)
 195:       {
 196:         super.setSelected(b);
 197:       }  
 198:   }
 199: 
 200:   /**
 201:    * Compatible with Sun's JDK.
 202:    */
 203:   private static final long serialVersionUID = -3128248873429850443L;
 204:     
 205:   /**
 206:    * Constructs an unselected toggle button with no text or icon.
 207:    */ 
 208:   public JToggleButton()
 209:   {
 210:     this(null, null, false);
 211:   }
 212: 
 213:   /**
 214:    * Constructs a toggle button using the labelling, state
 215:    * and icon specified by the supplied action.
 216:    *
 217:    * @param a the action to use to define the properties of the button.
 218:    */
 219:   public JToggleButton(Action a)
 220:   {
 221:     this();
 222:     setAction(a);
 223:   }
 224: 
 225:   /**
 226:    * Constructs an unselected toggle button with the supplied icon
 227:    * and no text.
 228:    *
 229:    * @param icon the icon to use.
 230:    */
 231:   public JToggleButton(Icon icon)
 232:   { 
 233:     this(null, icon, false);
 234:   }    
 235:   
 236:   /**
 237:    * Constructs a toggle button with the supplied icon and state.
 238:    *
 239:    * @param icon the icon to use.
 240:    * @param selected if true, the toggle button is initially in the
 241:    *        selected state.  Otherwise, the button is unselected.
 242:    */
 243:   public JToggleButton(Icon icon, boolean selected) 
 244:   {
 245:     this(null, icon, selected);
 246:   }
 247:   
 248:   /**
 249:    * Constructs an unselected toggle button using the supplied text
 250:    * and no icon.
 251:    *
 252:    * @param text the text to use.
 253:    */ 
 254:   public JToggleButton(String text)
 255:   {
 256:     this(text, null, false);
 257:   }
 258:       
 259:   /**
 260:    * Constructs a toggle button with the supplied text and state.
 261:    *
 262:    * @param text the text to use.
 263:    * @param selected if true, the toggle button is initially in the
 264:    *        selected state.  Otherwise, the button is unselected.
 265:    */
 266:   public JToggleButton(String text, boolean selected)
 267:   {
 268:     this(text, null, selected);
 269:   }
 270: 
 271:   /**
 272:    * Constructs an unselected toggle button with the supplied text
 273:    * and icon.
 274:    *
 275:    * @param text the text to use.
 276:    * @param icon the icon to use.
 277:    */
 278:   public JToggleButton(String text, Icon icon)
 279:   {
 280:     this(text, icon, false);
 281:   }
 282: 
 283:   /**
 284:    * Constructs a toggle button with the supplied text, icon and state.
 285:    *
 286:    * @param text the text to use.
 287:    * @param icon the icon to use.
 288:    * @param selected if true, the toggle button is initially in the
 289:    *        selected state.  Otherwise, the button is unselected.
 290:    */
 291:   public JToggleButton (String text, Icon icon, boolean selected) 
 292:   {
 293:     super();
 294:     setModel(new ToggleButtonModel());  
 295:     init(text, icon);
 296:     model.setSelected(selected);
 297:     setAlignmentX(LEFT_ALIGNMENT);
 298:   }
 299: 
 300:   /**
 301:    * Gets the AccessibleContext associated with this <code>JToggleButton</code>.
 302:    * The context is created, if necessary.
 303:    *
 304:    * @return the associated context
 305:    */
 306:   public AccessibleContext getAccessibleContext()
 307:   {
 308:     /* Create the context if this is the first request */
 309:     if (accessibleContext == null)
 310:       {
 311:         /* Create the context */
 312:     accessibleContext = new AccessibleJToggleButton();
 313:       }
 314:     return accessibleContext;
 315:   }
 316:   
 317:   /**
 318:    * Returns a string that specifies the name of the Look and Feel
 319:    * class that renders this component.
 320:    *
 321:    * @return The Look and Feel UI class in <code>String</code> form.
 322:    */
 323:   public String getUIClassID()
 324:   {
 325:     return "ToggleButtonUI";
 326:   }
 327:   
 328:   /**
 329:    * Returns a textual representation of this component for debugging.
 330:    * Users should not depend on anything as regards the content or formatting
 331:    * of this string, except for the fact that the returned string may never be
 332:    * null (only empty).
 333:    *
 334:    * @return the component in <code>String</code> form for debugging.
 335:    */
 336:   protected  String paramString()
 337:   {
 338:     return super.paramString();
 339:   }
 340:   
 341:   /**
 342:    * This method resets the toggle button's UI delegate to the default UI for
 343:    * the current look and feel.
 344:    */
 345:   public void updateUI()
 346:   {    
 347:     setUI((ButtonUI)UIManager.getUI(this));
 348:   }
 349: 
 350: }
 351: 
 352: