Class Binding<V>

java.lang.Object
org.inspirenxe.strata.core.state.Binding<V>
Type Parameters:
V - the type of the property's value

public final class Binding<V> extends Object
One property of one component kept in step with a Source, made by Component.bind. The component's node holds it and calls attach(BindingQueue) and detach() as the component joins and leaves a shown tree.

While attached, the binding is a dependent of every StateImpl its source read the last time it was evaluated. A change to any of them marks it dirty, from any thread, and puts it on its root's BindingQueue, which evaluates it on the UI thread: the source runs inside a Tracking frame, the dependencies are replaced by what it read, and the value is written to the property unless the property already equals it.

The binding reads the property through the key's check, so a converted key compares and writes back the model's value, and writes nothing back while the property's value does not convert. While it does not, a component that is a ConversionTarget shows the conversion's message as an error, which the binding takes away once a report converts again, once it writes the state's value, and when it is released.

When the source is a state and the key has reports, the binding also handles each report on the component, at the highest priority, so after the component's other handlers and before the handlers of the ancestors the report bubbles to, and writes the property's value to the state unless the two are equal. It writes inside a cause frame whose origin is an Origin.Binding of its source, so the control's requests do not fire for the write. It skips reports with that origin, so a value it set never comes back to the state, and reports that fire after attach before its first evaluation, so a value the control had before it read the source, such as a combo box selecting its first item when the items arrive, never replaces the state's.

A report fired by a step of an animation that has not reached its end, which puts IN_MOTION, is not written back either. The binding hands itself to the animation instead, which calls writeBack() once it ends or stops, so the state hears where the property came to rest and not every value on the way.

  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    static interface 
    Something running that bindings leave their write-backs with until it ends: an animation.
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    static final org.inspirenxe.strata.api.event.cause.CauseKey<Binding.Deferral>
    Put by every step of an animation but its last, with the animation as the value, so bindings leave its reports until it ends.
  • Constructor Summary

    Constructors
    Constructor
    Description
    Binding(org.inspirenxe.strata.api.component.Component<?> component, org.inspirenxe.strata.api.state.PropertyKey<?,V> key, org.inspirenxe.strata.api.state.Source<V> source, Supplier<org.inspirenxe.strata.api.event.cause.CauseStack> causes)
    Creates a binding that does nothing until attached.
  • Method Summary

    Modifier and Type
    Method
    Description
    void
    Starts following the source: handles the key's reports if the binding is two way, and marks the binding dirty on the queue.
    void
    Stops following the source: drops the report handlers and every dependency, so no state refers to this binding any more.
    void
    Evaluates the source and sets the property, if the binding is dirty and attached.
    boolean
    Returns whether the binding is attached.
    org.inspirenxe.strata.api.state.PropertyKey<?,V>
    key()
    Returns the property this binding sets.
    void
    Ends the binding for good, when the component unbinds the key or binds it again: detaches it and takes away the conversion error it showed, if any.
    Names the component and key, for the cycle report.
    void
    Writes the property's value to the state unless they are equal, as a report does, for a report an animation deferred.

    Methods inherited from class Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
  • Field Details

    • IN_MOTION

      public static final org.inspirenxe.strata.api.event.cause.CauseKey<Binding.Deferral> IN_MOTION
      Put by every step of an animation but its last, with the animation as the value, so bindings leave its reports until it ends.
  • Constructor Details

    • Binding

      public Binding(org.inspirenxe.strata.api.component.Component<?> component, org.inspirenxe.strata.api.state.PropertyKey<?,V> key, org.inspirenxe.strata.api.state.Source<V> source, Supplier<org.inspirenxe.strata.api.event.cause.CauseStack> causes)
      Creates a binding that does nothing until attached.
      Parameters:
      component - the component whose property it sets
      key - the property; must apply to the component's type, which Component.bind checked
      source - the source
      causes - the cause stack of the component's factory, where the binding opens its frame while it writes
  • Method Details

    • key

      public org.inspirenxe.strata.api.state.PropertyKey<?,V> key()
      Returns the property this binding sets.
      Returns:
      the key
    • isAttached

      public boolean isAttached()
      Returns whether the binding is attached.
      Returns:
      true between attach(BindingQueue) and detach()
    • attach

      public void attach(BindingQueue queue)
      Starts following the source: handles the key's reports if the binding is two way, and marks the binding dirty on the queue. The caller evaluates it once the tree it joined is attached. Does nothing if already attached. Call on the UI thread.
      Parameters:
      queue - the queue of the root the component joined
    • detach

      public void detach()
      Stops following the source: drops the report handlers and every dependency, so no state refers to this binding any more. Does nothing if not attached. Call on the UI thread.
    • release

      public void release()
      Ends the binding for good, when the component unbinds the key or binds it again: detaches it and takes away the conversion error it showed, if any. Call on the UI thread.
    • evaluate

      public void evaluate()
      Evaluates the source and sets the property, if the binding is dirty and attached. Call on the UI thread. If the source throws, the binding still follows the states it read before throwing, so a change to one of them evaluates it again, and the exception goes on to the caller.
    • writeBack

      public void writeBack()
      Writes the property's value to the state unless they are equal, as a report does, for a report an animation deferred. A value that does not convert is not written, so the state keeps its last valid value, and a ConversionTarget shows the conversion's message until a value converts again. Does nothing for a one-way binding, or one that is detached or not evaluated since it attached. Call on the UI thread.
    • toString

      public String toString()
      Names the component and key, for the cycle report.
      Overrides:
      toString in class Object
      Returns:
      for example CheckBoxImpl@1f2a.toggle.selected