Spec-Zone .ru
спецификации, руководства, описания, API
|
001/* 002 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. Oracle designates this 008 * particular file as subject to the "Classpath" exception as provided 009 * by Oracle in the LICENSE file that accompanied this code. 010 * 011 * This code is distributed in the hope that it will be useful, but WITHOUT 012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 014 * version 2 for more details (a copy is included in the LICENSE file that 015 * accompanied this code). 016 * 017 * You should have received a copy of the GNU General Public License version 018 * 2 along with this work; if not, write to the Free Software Foundation, 019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 020 * 021 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 022 * or visit www.oracle.com if you need additional information or have any 023 * questions. 024 */ 025 026package javafx.scene.control; 027 028import javafx.beans.property.BooleanProperty; 029import javafx.beans.property.BooleanPropertyBase; 030import javafx.beans.property.ObjectProperty; 031import javafx.beans.property.ObjectPropertyBase; 032import javafx.scene.Node; 033 034/** 035 * <p> 036 * A RadioMenuItem is a {@link MenuItem} that can be toggled (it uses 037 * the {@link javafx.scene.control.Toggle Toggle} mixin). This means that 038 * RadioMenuItem has an API very similar in nature to other controls that use 039 * {@link javafx.scene.control.Toggle Toggle}, such as 040 * {@link javafx.scene.control.RadioButton} and 041 * {@link javafx.scene.control.ToggleButton}. RadioMenuItem is 042 * specifically designed for use within a {@code Menu}, so refer to that class 043 * API documentation for more information on how to add a RadioMenuItem into it. 044 * <p> 045 * To create a simple, ungrouped RadioMenuItem, do the following: 046<pre><code> 047RadioMenuItem radioItem = new RadioMenuItem("radio text"); 048radioItem.setSelected(false); 049radioItem.setOnAction(new EventHandler<ActionEvent>() { 050 @Override public void handle(ActionEvent e) { 051 System.out.println("radio toggled"); 052 } 053}); 054</code></pre> 055 * <p> 056 * The problem with the example above is that this offers no benefit over using 057 * a normal MenuItem. As already mentioned, the purpose of a 058 * RadioMenuItem is to offer 059 * multiple choices to the user, and only allow for one of these choices to be 060 * selected at any one time (i.e. the selection should be <i>mutually exclusive</i>). 061 * To achieve this, you can place zero or more RadioMenuItem's into groups. When 062 * in groups, only one RadioMenuItem at a time within that group can be selected. 063 * To put two RadioMenuItem instances into the same group, simply assign them 064 * both the same value for {@code toggleGroup}. For example: 065<pre><code> 066ToggleGroup toggleGroup = new ToggleGroup(); 067 068RadioMenuItem radioItem1 = new RadioMenuItem("Option 1"); 069radioItem.setOnAction(new EventHandler<ActionEvent>() { 070 @Override public void handle(ActionEvent e) { 071 System.out.println("radio toggled"); 072 } 073}); 074radioItem1.setToggleGroup(toggleGroup); 075RadioMenuItem radioItem2 = new RadioMenuItem("Option 2"); 076radioItem.setOnAction(new EventHandler<ActionEvent>() { 077 @Override public void handle(ActionEvent e) { 078 System.out.println("radio toggled"); 079 } 080}); 081radioItem2.setToggleGroup(toggleGroup); 082 083</code></pre> 084 * 085 * In this example, with both RadioMenuItem's assigned to the same 086 * {@link javafx.scene.control.ToggleGroup ToggleGroup}, only one item may be 087 * selected at any one time, and should 088 * the selection change, the ToggleGroup will take care of deselecting the 089 * previous item. 090</code></pre> 091 * 092 * @see MenuItem 093 * @see Menu 094 */ 095public class RadioMenuItem extends MenuItem implements Toggle { 096 097 /*************************************************************************** 098 * * 099 * Constructors * 100 * * 101 **************************************************************************/ 102 103 private RadioMenuItem() { 104 this(null,null); 105 } 106 107 /** 108 * Constructs a RadioMenuItem and sets the display text with the specified text. 109 */ 110 public RadioMenuItem(String text) { 111 this(text,null); 112 } 113 114 /** 115 * Constructs a RadioMenuItem and sets the display text with the specified text 116 * and sets the graphic {@link Node} to the given node. 117 */ 118 public RadioMenuItem(String text, Node graphic) { 119 super(text,graphic); 120 getStyleClass().add(DEFAULT_STYLE_CLASS); 121 } 122 123 124 125 /*************************************************************************** 126 * * 127 * Properties * 128 * * 129 **************************************************************************/ 130 131 // --- Toggle Group 132 private ObjectProperty<ToggleGroup> toggleGroup; 133 @Override public final void setToggleGroup(ToggleGroup value) { 134 toggleGroupProperty().set(value); 135 } 136 137 @Override public final ToggleGroup getToggleGroup() { 138 return toggleGroup == null ? null : toggleGroup.get(); 139 } 140 141 @Override public final ObjectProperty<ToggleGroup> toggleGroupProperty() { 142 if (toggleGroup == null) { 143 toggleGroup = new ObjectPropertyBase<ToggleGroup>() { 144 private ToggleGroup old; 145 @Override protected void invalidated() { 146 if (old != null) { 147 old.getToggles().remove(RadioMenuItem.this); 148 } 149 old = get(); 150 if (get() != null && !get().getToggles().contains(RadioMenuItem.this)) { 151 get().getToggles().add(RadioMenuItem.this); 152 } 153 } 154 155 @Override 156 public Object getBean() { 157 return RadioMenuItem.this; 158 } 159 160 @Override 161 public String getName() { 162 return "toggleGroup"; 163 } 164 }; 165 } 166 return toggleGroup; 167 } 168 169 170 // --- Selected 171 private BooleanProperty selected; 172 @Override public final void setSelected(boolean value) { 173 selectedProperty().set(value); 174 } 175 176 @Override public final boolean isSelected() { 177 return selected == null ? false : selected.get(); 178 } 179 180 @Override public final BooleanProperty selectedProperty() { 181 if (selected == null) { 182 selected = new BooleanPropertyBase() { 183 @Override protected void invalidated() { 184 if (getToggleGroup() != null) { 185 if (get()) { 186 getToggleGroup().selectToggle(RadioMenuItem.this); 187 } else if (getToggleGroup().getSelectedToggle() == RadioMenuItem.this) { 188 getToggleGroup().selectToggle(null); 189 } 190 } 191 192 if (isSelected()) { 193 getStyleClass().add(STYLE_CLASS_SELECTED); 194 } else { 195 getStyleClass().remove(STYLE_CLASS_SELECTED); 196 } 197 } 198 199 @Override 200 public Object getBean() { 201 return RadioMenuItem.this; 202 } 203 204 @Override 205 public String getName() { 206 return "selected"; 207 } 208 }; 209 } 210 return selected; 211 } 212 213 214 215 /*************************************************************************** 216 * * 217 * Inherited Public API * 218 * * 219 **************************************************************************/ 220 221 222 /*************************************************************************** 223 * * 224 * Stylesheet Handling * 225 * * 226 **************************************************************************/ 227 228 private static final String DEFAULT_STYLE_CLASS = "radio-menu-item"; 229 private static final String STYLE_CLASS_SELECTED = "selected"; 230}