/*
* Copyright (c) 2010, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javafx.scene.control;
import java.util.HashMap;
import java.util.List;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.collections.ListChangeListener.Change;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.collections.ObservableMap;
import com.sun.javafx.collections.VetoableListDecorator;
import com.sun.javafx.collections.TrackableObservableList;
A class which contains a reference to all Toggles
whose selected
variables should be managed such that only a single Toggle
within the ToggleGroup
may be selected at any one time. Generally ToggleGroups
are managed automatically simply by specifying the name of a ToggleGroup
on the Toggle
, but in some situations it is desirable to explicitly manage which ToggleGroup
is used by Toggles
.
Since: JavaFX 2.0
/**
* A class which contains a reference to all {@code Toggles} whose
* {@code selected} variables should be managed such that only a single
* <code>{@link Toggle}</code> within the {@code ToggleGroup} may be selected at
* any one time.
* <p>
* Generally {@code ToggleGroups} are managed automatically simply by specifying
* the name of a {@code ToggleGroup} on the <code>{@link Toggle}</code>, but in
* some situations it is desirable to explicitly manage which
* {@code ToggleGroup} is used by <code>{@link Toggle Toggles}</code>.
* </p>
* @since JavaFX 2.0
*/
public class ToggleGroup {
Creates a default ToggleGroup instance.
/**
* Creates a default ToggleGroup instance.
*/
public ToggleGroup() {
}
The list of toggles within the ToggleGroup.
Returns: the list of toggles within the ToggleGroup
/**
* The list of toggles within the ToggleGroup.
* @return the list of toggles within the ToggleGroup
*/
public final ObservableList<Toggle> getToggles() {
return toggles;
}
private final ObservableList<Toggle> toggles = new VetoableListDecorator<Toggle>(new TrackableObservableList<Toggle>() {
@Override protected void onChanged(Change<Toggle> c) {
while (c.next()) {
// Look through the removed toggles, and if any of them was the
// one and only selected toggle, then we will clear the selected
// toggle property.
for (Toggle t : c.getRemoved()) {
if (t.isSelected()) {
selectToggle(null);
}
}
// A Toggle can only be in one group at any one time. If the
// group is changed, then the toggle is removed from the old group prior to
// being added to the new group.
for (Toggle t: c.getAddedSubList()) {
if (!ToggleGroup.this.equals(t.getToggleGroup())) {
if (t.getToggleGroup() != null) {
t.getToggleGroup().getToggles().remove(t);
}
t.setToggleGroup(ToggleGroup.this);
}
}
// Look through all the added toggles and the very first selected
// toggle we encounter will become the one we make the selected
// toggle for this group.
for (Toggle t : c.getAddedSubList()) {
if (t.isSelected()) {
selectToggle(t);
break;
}
}
}
}
}) {
@Override protected void onProposedChange(List<Toggle> toBeAdded, int... indexes) {
for (Toggle t: toBeAdded) {
if (indexes[0] == 0 && indexes[1] == size()) {
// we don't need to check for duplicates because this is a setAll.
break;
}
if (toggles.contains(t)) {
throw new IllegalArgumentException("Duplicate toggles are not allow in a ToggleGroup.");
}
}
}
};
private final ReadOnlyObjectWrapper<Toggle> selectedToggle = new ReadOnlyObjectWrapper<Toggle>() {
// Note: "set" is really what I want here. If the selectedToggle property
// is bound, then this whole chunk of code is bypassed, which is exactly
// what I want to do.
@Override public void set(final Toggle newSelectedToggle) {
if (isBound()) {
throw new java.lang.RuntimeException("A bound value cannot be set.");
}
final Toggle old = get();
if (old == newSelectedToggle) {
return;
}
if (setSelected(newSelectedToggle, true) ||
(newSelectedToggle != null && newSelectedToggle.getToggleGroup() == ToggleGroup.this) ||
(newSelectedToggle == null)) {
if (old == null || old.getToggleGroup() == ToggleGroup.this || !old.isSelected()) {
setSelected(old, false);
}
super.set(newSelectedToggle);
}
}
};
Selects the toggle.
Params: - value – The
Toggle
that is to be selected.
/**
* Selects the toggle.
*
* @param value The {@code Toggle} that is to be selected.
*/
// Note that since selectedToggle is a read-only property, the selectToggle method is some
// other method than setSelectedToggle, even though it is in essence doing the same thing
public final void selectToggle(Toggle value) { selectedToggle.set(value); }
Gets the selected Toggle
. Returns: Toggle The selected toggle.
/**
* Gets the selected {@code Toggle}.
* @return Toggle The selected toggle.
*/
public final Toggle getSelectedToggle() { return selectedToggle.get(); }
The selected toggle.
Returns: the selected toggle
/**
* The selected toggle.
* @return the selected toggle
*/
public final ReadOnlyObjectProperty<Toggle> selectedToggleProperty() { return selectedToggle.getReadOnlyProperty(); }
private boolean setSelected(Toggle toggle, boolean selected) {
if (toggle != null &&
toggle.getToggleGroup() == this &&
!toggle.selectedProperty().isBound()) {
toggle.setSelected(selected);
return true;
}
return false;
}
// Clear the selected toggle only if there are no other toggles selected.
final void clearSelectedToggle() {
if (!selectedToggle.getValue().isSelected()) {
for (Toggle toggle: getToggles()) {
if (toggle.isSelected()) {
return;
}
}
}
selectedToggle.set(null);
}
*
*
*
/*************************************************************************
* *
* *
* *
*************************************************************************/
private static final Object USER_DATA_KEY = new Object();
// A map containing a set of properties for this scene
private ObservableMap<Object, Object> properties;
Returns an observable map of properties on this node for use primarily
by application developers.
Returns: an observable map of properties on this node for use primarily
by application developers Since: JavaFX 8u40
/**
* Returns an observable map of properties on this node for use primarily
* by application developers.
*
* @return an observable map of properties on this node for use primarily
* by application developers
*
* @since JavaFX 8u40
*/
public final ObservableMap<Object, Object> getProperties() {
if (properties == null) {
properties = FXCollections.observableMap(new HashMap<Object, Object>());
}
return properties;
}
Tests if ToggleGroup has properties.
Returns: true if node has properties. Since: JavaFX 8u40
/**
* Tests if ToggleGroup has properties.
* @return true if node has properties.
*
* @since JavaFX 8u40
*/
public boolean hasProperties() {
return properties != null && !properties.isEmpty();
}
Convenience method for setting a single Object property that can be retrieved at a later date. This is functionally equivalent to calling the getProperties().put(Object key, Object value) method. This can later be retrieved by calling getUserData()
. Params: - value – The value to be stored - this can later be retrieved by calling
getUserData()
.
Since: JavaFX 8u40
/**
* Convenience method for setting a single Object property that can be
* retrieved at a later date. This is functionally equivalent to calling
* the getProperties().put(Object key, Object value) method. This can later
* be retrieved by calling {@link ToggleGroup#getUserData()}.
*
* @param value The value to be stored - this can later be retrieved by calling
* {@link ToggleGroup#getUserData()}.
*
* @since JavaFX 8u40
*/
public void setUserData(Object value) {
getProperties().put(USER_DATA_KEY, value);
}
Returns a previously set Object property, or null if no such property has been set using the setUserData(Object)
method. Returns: The Object that was previously set, or null if no property
has been set or if null was set. Since: JavaFX 8u40
/**
* Returns a previously set Object property, or null if no such property
* has been set using the {@link ToggleGroup#setUserData(java.lang.Object)} method.
*
* @return The Object that was previously set, or null if no property
* has been set or if null was set.
*
* @since JavaFX 8u40
*/
public Object getUserData() {
return getProperties().get(USER_DATA_KEY);
}
}