/*
* Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package javafx.scene.control;
import javafx.beans.property.
BooleanProperty;
import javafx.beans.property.
BooleanPropertyBase;
import javafx.beans.property.
ObjectProperty;
import javafx.beans.property.
ObjectPropertyBase;
import javafx.scene.
Node;
/**
* <p>
* A RadioMenuItem is a {@link MenuItem} that can be toggled (it uses
* the {@link javafx.scene.control.Toggle Toggle} mixin). This means that
* RadioMenuItem has an API very similar in nature to other controls that use
* {@link javafx.scene.control.Toggle Toggle}, such as
* {@link javafx.scene.control.RadioButton} and
* {@link javafx.scene.control.ToggleButton}. RadioMenuItem is
* specifically designed for use within a {@code Menu}, so refer to that class
* API documentation for more information on how to add a RadioMenuItem into it.
* <p>
* To create a simple, ungrouped RadioMenuItem, do the following:
<pre><code>
RadioMenuItem radioItem = new RadioMenuItem("radio text");
radioItem.setSelected(false);
radioItem.setOnAction(new EventHandler<ActionEvent>() {
@Override public void handle(ActionEvent e) {
System.out.println("radio toggled");
}
});
</code></pre>
* <p>
* The problem with the example above is that this offers no benefit over using
* a normal MenuItem. As already mentioned, the purpose of a
* RadioMenuItem is to offer
* multiple choices to the user, and only allow for one of these choices to be
* selected at any one time (i.e. the selection should be <i>mutually exclusive</i>).
* To achieve this, you can place zero or more RadioMenuItem's into groups. When
* in groups, only one RadioMenuItem at a time within that group can be selected.
* To put two RadioMenuItem instances into the same group, simply assign them
* both the same value for {@code toggleGroup}. For example:
<pre><code>
ToggleGroup toggleGroup = new ToggleGroup();
RadioMenuItem radioItem1 = new RadioMenuItem("Option 1");
radioItem.setOnAction(new EventHandler<ActionEvent>() {
@Override public void handle(ActionEvent e) {
System.out.println("radio toggled");
}
});
radioItem1.setToggleGroup(toggleGroup);
RadioMenuItem radioItem2 = new RadioMenuItem("Option 2");
radioItem.setOnAction(new EventHandler<ActionEvent>() {
@Override public void handle(ActionEvent e) {
System.out.println("radio toggled");
}
});
radioItem2.setToggleGroup(toggleGroup);
</code></pre>
*
* In this example, with both RadioMenuItem's assigned to the same
* {@link javafx.scene.control.ToggleGroup ToggleGroup}, only one item may be
* selected at any one time, and should
* the selection change, the ToggleGroup will take care of deselecting the
* previous item.
</code></pre>
*
* @see MenuItem
* @see Menu
* @since JavaFX 2.0
*/
public class
RadioMenuItem extends
MenuItem implements
Toggle {
/***************************************************************************
* *
* Constructors *
* *
**************************************************************************/
/**
* Constructs a RadioMenuItem with no display text.
*/
public
RadioMenuItem() {
this(null,null);
}
/**
* Constructs a RadioMenuItem and sets the display text with the specified text.
*/
public
RadioMenuItem(
String text) {
this(
text,null);
}
/**
* Constructs a RadioMenuItem and sets the display text with the specified text
* and sets the graphic {@link Node} to the given node.
*/
public
RadioMenuItem(
String text,
Node graphic) {
super(
text,
graphic);
getStyleClass().
add(
DEFAULT_STYLE_CLASS);
}
/***************************************************************************
* *
* Properties *
* *
**************************************************************************/
// --- Toggle Group
/**
* Represents the {@link ToggleGroup} that this RadioMenuItem belongs to.
*/
private
ObjectProperty<
ToggleGroup>
toggleGroup;
@
Override public final void
setToggleGroup(
ToggleGroup value) {
toggleGroupProperty().
set(
value);
}
@
Override public final
ToggleGroup getToggleGroup() {
return
toggleGroup == null ? null :
toggleGroup.
get();
}
@
Override public final
ObjectProperty<
ToggleGroup>
toggleGroupProperty() {
if (
toggleGroup == null) {
toggleGroup = new
ObjectPropertyBase<
ToggleGroup>() {
private
ToggleGroup old;
@
Override protected void
invalidated() {
if (
old != null) {
old.
getToggles().
remove(
RadioMenuItem.this);
}
old =
get();
if (
get() != null && !
get().
getToggles().
contains(
RadioMenuItem.this)) {
get().
getToggles().
add(
RadioMenuItem.this);
}
}
@
Override
public
Object getBean() {
return
RadioMenuItem.this;
}
@
Override
public
String getName() {
return "toggleGroup";
}
};
}
return
toggleGroup;
}
// --- Selected
private
BooleanProperty selected;
@
Override public final void
setSelected(boolean
value) {
selectedProperty().
set(
value);
}
@
Override public final boolean
isSelected() {
return
selected == null ? false :
selected.
get();
}
@
Override public final
BooleanProperty selectedProperty() {
if (
selected == null) {
selected = new
BooleanPropertyBase() {
@
Override protected void
invalidated() {
if (
getToggleGroup() != null) {
if (
get()) {
getToggleGroup().
selectToggle(
RadioMenuItem.this);
} else if (
getToggleGroup().
getSelectedToggle() ==
RadioMenuItem.this) {
getToggleGroup().
clearSelectedToggle();
}
}
if (
isSelected()) {
getStyleClass().
add(
STYLE_CLASS_SELECTED);
} else {
getStyleClass().
remove(
STYLE_CLASS_SELECTED);
}
}
@
Override
public
Object getBean() {
return
RadioMenuItem.this;
}
@
Override
public
String getName() {
return "selected";
}
};
}
return
selected;
}
/***************************************************************************
* *
* Inherited Public API *
* *
**************************************************************************/
/***************************************************************************
* *
* Stylesheet Handling *
* *
**************************************************************************/
private static final
String DEFAULT_STYLE_CLASS = "radio-menu-item";
private static final
String STYLE_CLASS_SELECTED = "selected";
}