1/*
2 * Copyright (c) 1997, 2015, 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 */
25package javax.swing;
26
27import java.beans.JavaBean;
28import java.beans.BeanProperty;
29import java.io.ObjectOutputStream;
30import java.io.IOException;
31
32import javax.accessibility.*;
33
34/**
35 * An implementation of a radio button menu item.
36 * A <code>JRadioButtonMenuItem</code> is
37 * a menu item that is part of a group of menu items in which only one
38 * item in the group can be selected. The selected item displays its
39 * selected state. Selecting it causes any other selected item to
40 * switch to the unselected state.
41 * To control the selected state of a group of radio button menu items,
42 * use a <code>ButtonGroup</code> object.
43 * <p>
44 * Menu items can be configured, and to some degree controlled, by
45 * <code><a href="Action.html">Action</a></code>s.  Using an
46 * <code>Action</code> with a menu item has many benefits beyond directly
47 * configuring a menu item.  Refer to <a href="Action.html#buttonActions">
48 * Swing Components Supporting <code>Action</code></a> for more
49 * details, and you can find more information in <a
50 * href="http://docs.oracle.com/javase/tutorial/uiswing/misc/action.html">How
51 * to Use Actions</a>, a section in <em>The Java Tutorial</em>.
52 * <p>
53 * Some menus can have several button groups with radio button menu items. In
54 * this case it is useful that clicking on one radio button menu item does not
55 * close the menu. Such behavior can be controlled either by client
56 * {@link JComponent#putClientProperty} or the Look and Feel
57 * {@link UIManager#put} property named
58 * {@code "RadioButtonMenuItem.doNotCloseOnMouseClick"}. The default value is
59 * {@code false}. Setting the property to {@code true} prevents the menu from
60 * closing when it is clicked by the mouse. If the client property is set its
61 * value is always used; otherwise the {@literal L&F} property is queried.
62 * Note: some {@code L&F}s may ignore this property. All built-in {@code L&F}s
63 * inherit this behaviour.
64 * <p>
65 * For further documentation and examples see
66 * <a
67 href="http://docs.oracle.com/javase/tutorial/uiswing/components/menu.html">How to Use Menus</a>,
68 * a section in <em>The Java Tutorial.</em>
69 * <p>
70 * <strong>Warning:</strong> Swing is not thread safe. For more
71 * information see <a
72 * href="package-summary.html#threading">Swing's Threading
73 * Policy</a>.
74 * <p>
75 * <strong>Warning:</strong>
76 * Serialized objects of this class will not be compatible with
77 * future Swing releases. The current serialization support is
78 * appropriate for short term storage or RMI between applications running
79 * the same version of Swing.  As of 1.4, support for long term storage
80 * of all JavaBeans&trade;
81 * has been added to the <code>java.beans</code> package.
82 * Please see {@link java.beans.XMLEncoder}.
83 *
84 * @author Georges Saab
85 * @author David Karlton
86 * @see ButtonGroup
87 * @since 1.2
88 */
89@JavaBean(description = "A component within a group of menu items which can be selected.")
90@SwingContainer(false)
91@SuppressWarnings("serial") // Same-version serialization only
92public class JRadioButtonMenuItem extends JMenuItem implements Accessible {
93    /**
94     * @see #getUIClassID
95     * @see #readObject
96     */
97    private static final String uiClassID = "RadioButtonMenuItemUI";
98
99    /**
100     * Creates a <code>JRadioButtonMenuItem</code> with no set text or icon.
101     */
102    public JRadioButtonMenuItem() {
103        this(null, null, false);
104    }
105
106    /**
107     * Creates a <code>JRadioButtonMenuItem</code> with an icon.
108     *
109     * @param icon the <code>Icon</code> to display on the
110     *          <code>JRadioButtonMenuItem</code>
111     */
112    public JRadioButtonMenuItem(Icon icon) {
113        this(null, icon, false);
114    }
115
116    /**
117     * Creates a <code>JRadioButtonMenuItem</code> with text.
118     *
119     * @param text the text of the <code>JRadioButtonMenuItem</code>
120     */
121    public JRadioButtonMenuItem(String text) {
122        this(text, null, false);
123    }
124
125    /**
126     * Creates a radio button menu item whose properties are taken from the
127     * <code>Action</code> supplied.
128     *
129     * @param  a the <code>Action</code> on which to base the radio
130     *          button menu item
131     *
132     * @since 1.3
133     */
134    public JRadioButtonMenuItem(Action a) {
135        this();
136        setAction(a);
137    }
138
139    /**
140     * Creates a radio button menu item with the specified text
141     * and <code>Icon</code>.
142     *
143     * @param text the text of the <code>JRadioButtonMenuItem</code>
144     * @param icon the icon to display on the <code>JRadioButtonMenuItem</code>
145     */
146    public JRadioButtonMenuItem(String text, Icon icon) {
147        this(text, icon, false);
148    }
149
150    /**
151     * Creates a radio button menu item with the specified text
152     * and selection state.
153     *
154     * @param text the text of the <code>CheckBoxMenuItem</code>
155     * @param selected the selected state of the <code>CheckBoxMenuItem</code>
156     */
157    public JRadioButtonMenuItem(String text, boolean selected) {
158        this(text);
159        setSelected(selected);
160    }
161
162    /**
163     * Creates a radio button menu item with the specified image
164     * and selection state, but no text.
165     *
166     * @param icon  the image that the button should display
167     * @param selected  if true, the button is initially selected;
168     *                  otherwise, the button is initially unselected
169     */
170    public JRadioButtonMenuItem(Icon icon, boolean selected) {
171        this(null, icon, selected);
172    }
173
174    /**
175     * Creates a radio button menu item that has the specified
176     * text, image, and selection state.  All other constructors
177     * defer to this one.
178     *
179     * @param text  the string displayed on the radio button
180     * @param icon  the image that the button should display
181     * @param selected if {@code true}, the button is initially selected,
182     *                 otherwise, the button is initially unselected
183     */
184    public JRadioButtonMenuItem(String text, Icon icon, boolean selected) {
185        super(text, icon);
186        setModel(new JToggleButton.ToggleButtonModel());
187        setSelected(selected);
188        setFocusable(false);
189    }
190
191    /**
192     * Returns the name of the L&amp;F class that renders this component.
193     *
194     * @return the string "RadioButtonMenuItemUI"
195     * @see JComponent#getUIClassID
196     * @see UIDefaults#getUI
197     */
198    @BeanProperty(bound = false)
199    public String getUIClassID() {
200        return uiClassID;
201    }
202
203    /**
204     * See <code>readObject</code> and <code>writeObject</code> in
205     * <code>JComponent</code> for more
206     * information about serialization in Swing.
207     */
208    private void writeObject(ObjectOutputStream s) throws IOException {
209        s.defaultWriteObject();
210        if (getUIClassID().equals(uiClassID)) {
211            byte count = JComponent.getWriteObjCounter(this);
212            JComponent.setWriteObjCounter(this, --count);
213            if (count == 0 && ui != null) {
214                ui.installUI(this);
215            }
216        }
217    }
218
219
220    /**
221     * Returns a string representation of this
222     * <code>JRadioButtonMenuItem</code>.  This method
223     * is intended to be used only for debugging purposes, and the
224     * content and format of the returned string may vary between
225     * implementations. The returned string may be empty but may not
226     * be <code>null</code>.
227     *
228     * @return  a string representation of this
229     *          <code>JRadioButtonMenuItem</code>
230     */
231    protected String paramString() {
232        return super.paramString();
233    }
234
235    /**
236     * Overriden to return true, JRadioButtonMenuItem supports
237     * the selected state.
238     */
239    boolean shouldUpdateSelectedStateFromAction() {
240        return true;
241    }
242
243/////////////////
244// Accessibility support
245////////////////
246
247    /**
248     * Gets the AccessibleContext associated with this JRadioButtonMenuItem.
249     * For JRadioButtonMenuItems, the AccessibleContext takes the form of an
250     * AccessibleJRadioButtonMenuItem.
251     * A new AccessibleJRadioButtonMenuItem instance is created if necessary.
252     *
253     * @return an AccessibleJRadioButtonMenuItem that serves as the
254     *         AccessibleContext of this JRadioButtonMenuItem
255     */
256    @BeanProperty(bound = false)
257    public AccessibleContext getAccessibleContext() {
258        if (accessibleContext == null) {
259            accessibleContext = new AccessibleJRadioButtonMenuItem();
260        }
261        return accessibleContext;
262    }
263
264    /**
265     * This class implements accessibility support for the
266     * <code>JRadioButtonMenuItem</code> class.  It provides an
267     * implementation of the Java Accessibility API appropriate to
268     * <code>JRadioButtonMenuItem</code> user-interface elements.
269     * <p>
270     * <strong>Warning:</strong>
271     * Serialized objects of this class will not be compatible with
272     * future Swing releases. The current serialization support is
273     * appropriate for short term storage or RMI between applications running
274     * the same version of Swing.  As of 1.4, support for long term storage
275     * of all JavaBeans&trade;
276     * has been added to the <code>java.beans</code> package.
277     * Please see {@link java.beans.XMLEncoder}.
278     */
279    @SuppressWarnings("serial") // Same-version serialization only
280    protected class AccessibleJRadioButtonMenuItem extends AccessibleJMenuItem {
281        /**
282         * Get the role of this object.
283         *
284         * @return an instance of AccessibleRole describing the role of the
285         * object
286         */
287        public AccessibleRole getAccessibleRole() {
288            return AccessibleRole.RADIO_BUTTON;
289        }
290    } // inner class AccessibleJRadioButtonMenuItem
291}
292