All Downloads are FREE. Search and download functionalities are using the official Maven repository.

swingtree.UIForAnyToggleButton Maven / Gradle / Ivy

package swingtree;

import sprouts.From;
import sprouts.Var;

import javax.swing.JToggleButton;

/**
 *  An abstract precursor for swing tree builder nodes for {@link JToggleButton} instances.
 *  Extend this class to create a builder node for a custom {@link JToggleButton} subtype.
 *
 * @param  The type of this builder node.
 * @param  The type of the {@link JToggleButton} subtype which will be managed by this builder.
 */
public abstract class UIForAnyToggleButton extends UIForAnyButton
{
    /**
     *  Use this to dynamically bind the selection flag of the button to a {@link Var}
     *  property which will determine the selection state of the button based on the
     *  equality of the property value and the provided reference value.
     *  So if the first {@code state} argument is equal to the value of the {@code selection} property,
     *  the button will be selected, otherwise it will be deselected.
* A typical use case is to bind a button to an enum property, like so:
*
{@code
     *      // In your view model:
     *      enum Step { ONE, TWO, THREE }
     *      Var step = Var.of(Step.ONE);
     *
     *      // In your view:
     *      UI.radioButton("Two").isSelectedIf(Step.TWO, vm.getStep());
     *  }
* As you can see, the radio button will be selected if the enum property is equal to the supplied enum value * and deselected otherwise.
*
* Hint: Use {@code myProperty.fire(From.VIEW_MODEL)} in your view model to send the property value to this view component. * * @param state The reference value which this {@link JToggleButton} should represent. * @param selection The {@link sprouts.Var} instance which will be used * to dynamically model the selection state of the wrapped {@link JToggleButton} type * based on the equality of the {@code state} argument and the value of the property. * @param The type of the property value. * @return The current builder type, to allow for further method chaining. * @throws IllegalArgumentException if {@code selected} is {@code null}. */ public final I isSelectedIf( E state, Var selection ) { NullUtil.nullArgCheck(state, "state", Enum.class); NullUtil.nullArgCheck(selection, "selection", Var.class); NullUtil.nullPropertyCheck(selection, "selection", "Null is not a valid selection state."); return _withOnShow( selection, (button,s) -> { _setSelectedSilently(button, state.equals(s)); }) ._with( button -> { _setSelectedSilently(button, state.equals(selection.get())); // When the user clicks the button, we update the selection property! // But only if the button is selected, otherwise we'll ignore the click. // And we also trigger "set" events for the button, so that other buttons // can be updated to reflect the new selection state. _onChange(button, event -> { if ( button.isSelected() ) selection.set(From.VIEW, state ).fireChange(From.VIEW_MODEL); }); }) ._this(); } }