/* JRadioButton.java -- 
   Copyright (C) 2002, 2004, 2005  Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package javax.swing;

import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
import javax.swing.plaf.ButtonUI;

/**
 * The <code>JRadioButton</code> component provides a visually selectable
 * button with mutually exclusive behaviour within a <code>ButtonGroup</code>.
 * A series of radio buttons can be used to provide options to the user,
 * where the user can only select one of the available options.  The state
 * of the button is provided by the superclass, <code>JToggleButton</code>.
 * <code>JRadioButton</code> adds the additional behaviour, that if two
 * or more radio buttons are grouped together, the selection of one implies
 * the deselection of the other buttons within the group.
 * <p>
 *
 * Buttons are grouped by adding each instance to a <code>ButtonGroup</code>.
 * The existence of such a grouping is not reflected visually, so other means
 * should be used to denote this.  For instance, the grouped buttons can be placed
 * within the same panel, possibly with an appropriate border to denote
 * the connection between the components.
 *
 * @author Michael Koch  (konqueror@gmx.de)
 * @author Graydon Hoare  (graydon@redhat.com)
 * @author Andrew John Hughes  (gnu_andrew@member.fsf.org)
 * @see JToggleButton
 * @see ButtonGroup
 * @since 1.2
 */
public class JRadioButton extends JToggleButton
{
  /**
   * Compatible with Sun's JDK.
   */
  private static final long serialVersionUID = 7751949583255506856L;

  /**
   * This class provides accessibility support for the toggle button.
   */
  protected class AccessibleJRadioButton
    extends AccessibleJToggleButton
  {
    private static final long serialVersionUID = 4850967637026120674L;

    /**
     * Constructor for the accessible toggle button.
     */
    protected AccessibleJRadioButton()
    {
        /* Call the superclass to register for events */
        super();
    }

    /**
     * Returns the accessible role for the toggle button.
     *
     * @return An instance of <code>AccessibleRole</code>, describing
     *         the role of the toggle button.
     */
    public AccessibleRole getAccessibleRole()
    {
      return AccessibleRole.RADIO_BUTTON;
    }

  }

  /**
   * Constructs an unselected radio button with no text or icon.
   */ 
  public JRadioButton()
  {
    this(null, null, false);
  }
    
  /**
   * Constructs a radio button using the labelling, state
   * and icon specified by the supplied action.
   *
   * @param a the action to use to define the properties of the button.
   */
  public JRadioButton(Action a)
  {
    this();
    setAction(a);
  }

  /**
   * Constructs an unselected radio button with the supplied icon
   * and no text.
   *
   * @param icon the icon to use.
   */
  public JRadioButton(Icon icon)
  { 
    this(null, icon, false);
  }    
  
  /**
   * Constructs a radio button with the supplied icon and state.
   *
   * @param icon the icon to use.
   * @param selected if true, the radio button is initially in the
   *        selected state.  Otherwise, the button is unselected.
   */
  public JRadioButton(Icon icon, boolean selected)
  { 
    this(null, icon, selected);
  }    
  
  /**
   * Constructs an unselected radio button using the supplied text
   * and no icon.
   *
   * @param text the text to use.
   */
  public JRadioButton(String text)
  {
    this(text, null, false);
  }

  /**
   * Constructs a radio button with the supplied text and state.
   *
   * @param text the text to use.
   * @param selected if true, the radio button is initially in the
   *        selected state.  Otherwise, the button is unselected.
   */
  public JRadioButton(String text, boolean selected)
  {
    this(text, null, selected);
  }
      
  /**
   * Constructs an unselected radio button with the supplied text
   * and icon.
   *
   * @param text the text to use.
   * @param icon the icon to use.
   */
  public JRadioButton(String text, Icon icon)
  {
    this(text, icon, false);
  }
  
  /**
   * Constructs a radio button with the supplied text, icon and state.
   *
   * @param text the text to use.
   * @param icon the icon to use.
   * @param selected if true, the radio button is initially in the
   *        selected state.  Otherwise, the button is unselected.
   */
  public JRadioButton(String text, Icon icon, boolean selected)
  {
    super(text, icon, selected);
    setBorderPainted(false);
    setHorizontalAlignment(LEADING);
  }
      
  /**
   * Returns the accessible context for this <code>JRadioButton</code>,
   * in the form of an instance of <code>AccessibleJRadioButton</code>.
   * The context is created, if necessary.
   *
   * @return the associated context
   */
  public AccessibleContext getAccessibleContext()
  {
    /* Create the context if this is the first request */
    if (accessibleContext == null)
      {
        /* Create the context */
	accessibleContext = new AccessibleJRadioButton();
      }
    return accessibleContext;
  }
  
  /**
   * Returns a string specifying the name of the Look and Feel UI class
   * that renders this component.
   *
   * @return the Look and Feel UI class for <code>JRadioButton</code>s
   *         as a <code>String</code>.
   */  
  public String getUIClassID()
  {
    return "RadioButtonUI";
  }
  
  /**
   * Returns a string representation of this component for debugging use.
   * Users should not depend on anything as regards the content or formatting
   * of this string, except for the fact that the returned string may never be
   * null (only empty).
   *
   * @return the component in <code>String</code> form for debugging.
   */  
  protected  String paramString()
  {
    return super.paramString();
  }
  
  /**
   * This method resets the radio button's UI delegate to the default UI for
   * the current look and feel.
   */
  public void updateUI()
  {
    /* 
       I can't see any difference between this and the superclass one,
       but Sun reimplements it... there is no RadioButtonUI class for it
       to be cast to.
    */
    setUI((ButtonUI) UIManager.getUI(this));
  }

}



