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