package de.saring.util.gui.javafx;
import javafx.beans.property.ObjectProperty;
import javafx.scene.control.Toggle;
import javafx.scene.control.ToggleGroup;
/**
* Utility class with various JavaFX property binding extensions.
*
* @author Stefan Saring
*/
public final class BindingUtils {
private BindingUtils() {
}
/**
* Binds the specified ToggleGroup to the specified ObjectProperty (this feature is missing in JavaFX).
* This binding is not fully bidirectional. The initial selection of the ToggleGroup will be taken from
* the current value of the ObjectProperty. Whenever the ToogleGroup selection changes (user input),
* the ObjectProperty will have the value of the selected Toggle. Changes to the ObjectProperty value
* will not be transferred to the current Toggle selection.<br/>
* All Toggle controls of the ToogleGroup must define an userData object which is a potential value
* of the bound ObjectProperty.<br/>
* This method is helpful for binding ToggleButton or RadioButton groups to appropriate view model
* properties.
*
* @param toggleGroup the toggle group to be bound
* @param property the object property to be bound
* @param <T> type of the object property to be bound
*/
public static <T> void bindToggleGroupToProperty(final ToggleGroup toggleGroup, final ObjectProperty<T> property) {
// check all toggles for required user data
toggleGroup.getToggles().forEach(toggle -> {
if (toggle.getUserData() == null) {
throw new IllegalArgumentException("The ToggleGroup contains at least one Toggle without user data!");
}
});
// select initial toggle for current property state
for (Toggle toggle : toggleGroup.getToggles()) {
if (property.getValue() != null && property.getValue().equals(toggle.getUserData())) {
toggleGroup.selectToggle(toggle);
break;
}
}
// update property value on toggle selection changes
toggleGroup.selectedToggleProperty().addListener((observable, oldValue, newValue) -> {
property.setValue((T) newValue.getUserData());
});
}
}