Package swingtree.api

Interface ItemStyler<T,C extends JComponent>

Type Parameters:
T - the type of the item of the bound property, supplied to this function as the first argument.
C - the type of the JComponent that the ComponentStyleDelegate is delegating to.
Functional Interface:
This is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference.

@FunctionalInterface public interface ItemStyler<T,C extends JComponent>
An ItemStyler is conceptually a union of a property observer and the Styler function, which is to say that it takes both the current item of a bound Val property and a ComponentStyleDelegate to produce a new ComponentStyleDelegate with some style properties applied to it (usually based on the supplied item).
Note that both parameters are immutable value oriented objects, so the function is pure and does not modify the original ComponentStyleDelegate or item.

This interface exists specifically for property driven styling through UIForAnySwing.withStyle(sprouts.Val, ItemStyler), whose whole purpose is thread safety in the decoupled threading mode (see EventProcessor.DECOUPLED):
Style gathering is owned by the UI thread, which means a plain Styler lambda which reads a property from its enclosing scope (through myProperty.get()) leaks the UI thread into application thread owned state. An ItemStyler closes that leak by receiving the item as an explicit argument, captured from the property change event on the property's owning thread and published to the UI thread, where this function is then evaluated safely.
So instead of:


   UI.label("...")
   .withRepaintOn(person)
   .withStyle( it -> it.backgroundColor(person.get().color()) ) // <- live read on the UI thread!
 
...you write:

   UI.label("...")
   .withStyle( person, (p, it) -> it.backgroundColor(p.color()) ) // <- captured item, no property access
 
...which also repaints automatically whenever the property changes, making a separate UIForAnySwing.withRepaintOn(sprouts.Observable) binding unnecessary.

When a single ItemStyler should follow several properties at once, merge them into one record with the composite view builder Viewable.of(Object, java.util.function.Function) (requires Sprouts 2.7.0 or above) and bind that one merged property, instead of chaining a UIForAnySwing.withStyle(sprouts.Val, ItemStyler) per property.

See Also:
  • Method Details

    • none

      static <T, C extends JComponent> ItemStyler<T,C> none()
      An ItemStyler that does nothing, meaning it simply returns the given ComponentStyleDelegate without applying any style to it. Conceptually speaking, this returns the null object of the ItemStyler type.
      Type Parameters:
      T - The type of the item of the bound property.
      C - The type of the JComponent that the ComponentStyleDelegate is delegating to.
      Returns:
      An ItemStyler that does nothing.
    • style

      ComponentStyleDelegate<C> style(T item, ComponentStyleDelegate<C> delegate) throws Exception
      Applies some style to the given ComponentStyleDelegate, usually based on the supplied property item, and returns a new ComponentStyleDelegate that has the style applied (if any).
      Note that this method deliberately requires the handling of checked exceptions at its invocation sites because there may be any number of implementations hiding behind this interface and so it is unwise to assume that all of them will be able to execute gracefully without throwing exceptions.
      Parameters:
      item - The current item of the bound property, captured from the property change event on the property's owning thread. Style based on this argument only, never on the property itself!
      delegate - The ComponentStyleDelegate to apply the style to.
      Returns:
      A new ComponentStyleDelegate that has the style applied.
      Throws:
      Exception - if the style could not be applied by the client code.
    • andThen

      default ItemStyler<T,C> andThen(ItemStyler<T,C> other)
      Returns a new ItemStyler that applies the style of this ItemStyler and then applies the style of the given ItemStyler.
      Parameters:
      other - the ItemStyler to apply after this one.
      Returns:
      a new ItemStyler that applies the style of this and then the given one.