Package swingtree

Class UIForAnyButton<I,B extends AbstractButton>

java.lang.Object
swingtree.UIForAnySwing<I,B>
swingtree.UIForAnyButton<I,B>
Type Parameters:
B - The type parameter for the component wrapped by an instance of this class.
Direct Known Subclasses:
UIForAnyMenuItem, UIForAnyToggleButton, UIForButton, UIForCheckBox, UIForSplitButton

public abstract class UIForAnyButton<I,B extends AbstractButton> extends UIForAnySwing<I,B>
The following is a more specialized type of builder node based on the UIForAnySwing builder type, and provides additional features associated with the more specialized AbstractButton" Swing component type. One of such features is the onClick(Action) method allowing for a more readable way of adding ActionListener instances to button types...

Please take a look at the living swing-tree documentation where you can browse a large collection of examples demonstrating how to use the API of this class.

  • Constructor Details

    • UIForAnyButton

      public UIForAnyButton()
  • Method Details

    • withText

      public final I withText(String text)
      Defines the single line of text the wrapped button type will display. If the value of text is null or empty string, nothing is displayed.
      Parameters:
      text - The new text to be set for the wrapped button type.
      Returns:
      This very builder to allow for method chaining.
    • withText

      public final I withText(sprouts.Val<String> text)
      Binds the provided Val property to the wrapped button type and sets the text of the button to the value of the property. Hint: Use myProperty.fire(From.VIEW_MODEL) in your view model to manually send the property value to this view component.
      Parameters:
      text - The view model property which should be bound to this UI.
      Returns:
      This very builder to allow for method chaining.
      Throws:
      IllegalArgumentException - if text is null.
    • withIcon

      public I withIcon(Icon icon)
      Use this to set the icon for the wrapped button type. This is in essence a convenience method to avoid peeking into this builder like so:
      
           UI.button("Something")
           .peek( button -> button.setIcon(...) );
        
      Parameters:
      icon - The Icon which should be displayed on the button.
      Returns:
      This very builder to allow for method chaining.
      Throws:
      IllegalArgumentException - if icon is null.
    • withIcon

      public I withIcon(int width, int height, ImageIcon icon)
      Takes the provided Icon and scales it to the provided width and height before displaying it on the wrapped button type.
      Parameters:
      width - The width of the icon.
      height - The height of the icon.
      icon - The Icon which should be scaled and displayed on the button.
      Returns:
      This very builder to allow for method chaining.
    • withIcon

      public I withIcon(int width, int height, IconDeclaration icon)
      Takes the provided IconDeclaration and scales it to the provided width and height before displaying it on the wrapped button type.
      Parameters:
      width - The width of the icon.
      height - The height of the icon.
      icon - The IconDeclaration which should be scaled and displayed on the button.
      Returns:
      This very builder to allow for method chaining.
    • withIcon

      public I withIcon(int width, int height, IconDeclaration icon, UI.FitComponent fitComponent)
      Takes the provided IconDeclaration and scales the corresponding icon it to the provided width and height before displaying it on the wrapped button type.
      Parameters:
      width - The width of the icon.
      height - The height of the icon.
      icon - The Icon which should be scaled and displayed on the button.
      fitComponent - The UI.FitComponent which determines how the icon should be scaled relative to the button.
      Returns:
      This very builder to allow for method chaining.
    • withIcon

      public I withIcon(ImageIcon icon, UI.FitComponent fitComponent)
      Sets the Icon property of the wrapped button type and scales it according to the provided UI.FitComponent policy. This icon is also used as the "pressed" and "disabled" icon if there is no explicitly set pressed icon.
      Parameters:
      icon - The SvgIcon which should be displayed on the button.
      fitComponent - The UI.FitComponent which determines how the icon should be scaled.
      Returns:
      This very builder to allow for method chaining.
    • withIcon

      public I withIcon(IconDeclaration icon, UI.FitComponent fitComponent)
    • withIcon

      public I withIcon(IconDeclaration icon)
      Use this to specify the icon for the wrapped button type. The icon is determined based on the provided IconDeclaration instance which is conceptually merely a resource path to the icon.
      Parameters:
      icon - The desired icon to be displayed on top of the button.
      Returns:
      This very builder to allow for method chaining.
    • withIcon

      public I withIcon(sprouts.Val<IconDeclaration> icon)
      Use this to dynamically set the icon property for the wrapped button type. When the icon wrapped by the provided property changes, then so does the icon displayed on this button.

      But note that you may not use the Icon or ImageIcon classes directly, instead you must use implementations of the IconDeclaration interface, which merely models the resource location of the icon, but does not load the whole icon itself.

      The reason for this distinction is the fact that traditional Swing icons are heavy objects whose loading may or may not succeed, and so they are not suitable for direct use in a property as part of your view model. Instead, you should use the IconDeclaration interface, which is a lightweight value object that merely models the resource location of the icon even if it is not yet loaded or even does not exist at all.

      This is especially useful in case of unit tests for you view model, where the icon may not be available at all, but you still want to test the behaviour of your view model.

      Parameters:
      icon - The Icon property which should be displayed on the button.
      Returns:
      This very builder to allow for method chaining.
      Throws:
      IllegalArgumentException - if icon is null.
    • withFontSize

      public I withFontSize(int size)
      Use this to set the size of the font of the wrapped button type.
      Parameters:
      size - The size of the font which should be displayed on the button.
      Returns:
      This very builder to allow for method chaining.
    • withFontSize

      public I withFontSize(sprouts.Val<Integer> size)
      Use this to dynamically set the size of the font of the wrapped button type through the provided view model property. When the integer wrapped by the provided property changes, then so does the font size of the text displayed on this button.
      Parameters:
      size - The size property of the font which should be displayed on the button.
      Returns:
      This very builder to allow for method chaining.
      Throws:
      IllegalArgumentException - if size is null.
    • withFont

      public final I withFont(Font font)
      Use this to set the font of the wrapped button type.
      Parameters:
      font - The font of the text which should be displayed on the button.
      Returns:
      This builder instance, to allow for method chaining.
      Throws:
      IllegalArgumentException - if font is null.
    • withFont

      public final I withFont(sprouts.Val<Font> font)
      Use this to dynamically set the font of the wrapped button type through the provided view model property. When the font wrapped by the provided property changes, then so does the font of the text displayed on this button.
      Parameters:
      font - The font property of the text which should be displayed on the button type.
      Returns:
      This builder instance, to allow for method chaining.
      Throws:
      IllegalArgumentException - if font is null.
      IllegalArgumentException - if font is a property which can wrap null.
    • isSelectedIf

      public final I isSelectedIf(boolean isSelected)
      Use this to set the selection state of the wrapped button type.
      Parameters:
      isSelected - The selection state of the wrapped button type, which translates to AbstractButton.setSelected(boolean).
      Returns:
      This builder instance, to allow for method chaining.
    • isSelectedIf

      public final I isSelectedIf(sprouts.Val<Boolean> selected)
      Use this to bind to a Var instance which will be used to dynamically model the selection state of the wrapped AbstractButton type.
      Parameters:
      selected - The Var instance which will be used to model the selection state of the wrapped button type.
      Returns:
      This very instance, which enables builder-style method chaining.
      Throws:
      IllegalArgumentException - if selected is null.
    • isSelectedIfNot

      public final I isSelectedIfNot(sprouts.Val<Boolean> selected)
      Use this to bind to a Var instance which will be used to dynamically model the inverse selection state of the wrapped AbstractButton type.
      Parameters:
      selected - The Var instance which will be used to model the inverse selection state of the wrapped button type.
      Returns:
      This very instance, which enables builder-style method chaining.
      Throws:
      IllegalArgumentException - if selected is null.
    • isSelectedIf

      public final I isSelectedIf(sprouts.Var<Boolean> selected)
      Use this to bind to a Var instance which will be used to dynamically model the selection state of the wrapped AbstractButton type.
      Parameters:
      selected - The Var instance which will be used to model the selection state of the wrapped button type.
      Returns:
      This very instance, which enables builder-style method chaining.
      Throws:
      IllegalArgumentException - if selected is null.
    • isSelectedIfNot

      public final I isSelectedIfNot(sprouts.Var<Boolean> selected)
      Use this to dynamically bind to a Var instance which will be used to dynamically model the inverse selection state of the wrapped AbstractButton type.
      Parameters:
      selected - The Var instance which will be used to model the inverse selection state of the wrapped button type.
      Returns:
      This very instance, which enables builder-style method chaining.
      Throws:
      IllegalArgumentException - if selected is null.
    • isSelectedIf

      public final <T> I isSelectedIf(T state, sprouts.Val<T> selection)
      Use this to dynamically bind the selection flag of the button to a Val 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 state argument is equal to the value of the 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:
      
            // In your view model:
            enum Step { ONE, TWO, THREE }
            Var<Step> 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 myProperty.fire(From.VIEW_MODEL) in your view model to send the property value to this view component.
      Type Parameters:
      T - The type of the property value.
      Parameters:
      state - The reference value which the button type should represent when selected.
      selection - The Val instance which will be used to dynamically model the selection state of the wrapped button type based on the equality of the state argument and the value of the property.
      Returns:
      The current builder type, to allow for further method chaining.
      Throws:
      IllegalArgumentException - if selected is null.
    • isSelectedIfNot

      public final <T> I isSelectedIfNot(T state, sprouts.Val<T> selection)
      This is the inverse of isSelectedIf(Object, Val). Use this to make the wrapped UI component dynamically deselected or selected, based on the equality between the supplied value and the property value.
      Hint: Use myProperty.fire(From.VIEW_MODEL) in your view model to send the property value to this view component.
      A typical use case is to bind to an enum property, like so:
      
            // In your view model:
            enum Step { ONE, TWO, THREE }
            Var<Step> step = Var.of(Step.ONE);
      
            // In your view:
            UI.radioButton("Not Two")
            .isSelectedIfNot(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.
      Type Parameters:
      T - The type of the value.
      Parameters:
      state - The value which, if equal to the supplied property value, makes the UI component deselected.
      selection - The enum property which, if equal to the supplied value, makes the UI component deselected.
      Returns:
      This very instance, which enables builder-style method chaining.
    • isPressedIf

      public final I isPressedIf(sprouts.Var<Boolean> var)
      Use this to dynamically bind to a Var instance which will be used to dynamically model the pressed state of the wrapped AbstractButton type.
      Parameters:
      var - The Var instance which will be used to model the pressed state of the wrapped button type.
      Returns:
      This very instance, which enables builder-style method chaining.
      Throws:
      IllegalArgumentException - if var is null.
    • _onModelChange

      protected final void _onModelChange(B button, Consumer<ChangeEvent> action)
    • isBorderPaintedIf

      public I isBorderPaintedIf(boolean borderPainted)
      Sets the AbstractButton.setBorderPainted(boolean) flag of the wrapped button type. If the flag is set to true, the border of the button will be painted. The default value for the borderPainted property is true. Some look and feels might not support the borderPainted property, in which case they ignore this.
      Parameters:
      borderPainted - Whether the border of the button should be painted.
      Returns:
      This very instance, which enables builder-style method chaining.
    • isBorderPaintedIf

      public I isBorderPaintedIf(sprouts.Val<Boolean> val)
      Binds the provided Val property to the AbstractButton.setBorderPainted(boolean) method., which means that whenever the value of the property changes, the border of the button will be painted or not. The default value for the borderPainted property is true. Some look and feels might not support the borderPainted property, in which case they ignore this.
      Parameters:
      val - Whether the border of the button should be painted.
      Returns:
      This very instance, which enables builder-style method chaining.
    • makePlain

      public final I makePlain()
      Effectively removes the native style of this button. Without an icon or text, one will not be able to recognize the button. Use this for buttons with a custom icon or clickable text!
      Returns:
      This very instance, which enables builder-style method chaining.
    • onChange

      public final I onChange(sprouts.Action<ComponentDelegate<B,ItemEvent>> action)
      This method adds the provided ItemListener instance to the wrapped button component.

      Parameters:
      action - The change action lambda which will be passed to the button component.
      Returns:
      This very instance, which enables builder-style method chaining.
      Throws:
      IllegalArgumentException - if action is null.
    • _onChange

      protected final void _onChange(B button, Consumer<ItemEvent> action)
    • onClick

      public I onClick(sprouts.Action<ComponentDelegate<B,ActionEvent>> action)
      This method enables a more readable way of adding ActionListener instances to button types. Additionally, to the other "onClick" method this method enables the involvement of the JComponent itself into the action supplied to it. This is very useful for changing the state of the JComponent when the action is being triggered.

      Parameters:
      action - an Action instance which will receive an ComponentDelegate containing important context information.
      Returns:
      This very instance, which enables builder-style method chaining.
      Throws:
      IllegalArgumentException - if action is null.
    • _onClick

      protected final void _onClick(B button, Consumer<ActionEvent> action)
    • withHorizontalAlignment

      public final I withHorizontalAlignment(UI.HorizontalAlignment horizontalAlign)
      A convenience method to avoid peeking into this builder like so:
      
           UI.button("Clickable!")
               .peek( button -> button.setHorizontalAlignment(...) );
        
      This sets the horizontal alignment of the icon and text.
      Parameters:
      horizontalAlign - The horizontal alignment which should be applied to the underlying component.
      Returns:
      This very builder to allow for method chaining.
      Throws:
      IllegalArgumentException - if horizontalAlign is null.
    • withHorizontalAlignment

      public final I withHorizontalAlignment(sprouts.Val<UI.HorizontalAlignment> horizontalAlign)
      A convenience method to avoid peeking into this builder like so:
      
           UI.button("Clickable!")
           .peek( button -> {
                property.onSetItem(v->button.setHorizontalAlignment(v.forSwing()));
                button.setHorizontalAlignment(property.get().forSwing());
           });
        
      This sets the horizontal alignment of the icon and text and also binds the provided property to the underlying component.
      Hint: Use myProperty.fire(From.VIEW_MODEL) in your view model to send the property value to this view component.
      Parameters:
      horizontalAlign - The horizontal alignment property which should be bound to the underlying component.
      Returns:
      This very builder to allow for method chaining.
      Throws:
      IllegalArgumentException - if horizontalAlign is null.
    • withVerticalAlignment

      public final I withVerticalAlignment(UI.VerticalAlignment verticalAlign)
      A convenience method to avoid peeking into this builder like so:
      
           UI.button("Clickable!")
               .peek( button -> button.setVerticalAlignment(...) );
        
      This sets the vertical alignment of the icon and text.
      Parameters:
      verticalAlign - The vertical alignment which should be applied to the underlying component.
      Returns:
      This very builder to allow for method chaining.
      Throws:
      IllegalArgumentException - if verticalAlign is null.
    • withVerticalAlignment

      public final I withVerticalAlignment(sprouts.Val<UI.VerticalAlignment> verticalAlign)
      A convenience method to avoid peeking into this builder like so:
      
           UI.button("Clickable!")
           .peek( button -> {
                property.onSetItem(v->button.setVerticalAlignment(v.forSwing()));
                button.setVerticalAlignment(property.get().forSwing());
           });
        
      This sets the vertical alignment of the icon and text and also binds the provided property to the underlying component.
      Hint: Use myProperty.fire(From.VIEW_MODEL) in your view model to send the property value to this view component.
      Parameters:
      verticalAlign - The vertical alignment property which should be bound to the underlying component.
      Returns:
      This very builder to allow for method chaining.
      Throws:
      IllegalArgumentException - if verticalAlign is null.
    • withHorizontalTextAlignment

      public final I withHorizontalTextAlignment(UI.HorizontalAlignment horizontalAlign)
      A convenience method to avoid peeking into this builder like so:
      
           UI.button("Clickable!")
               .peek( button -> button.setHorizontalTextPosition(...) );
        
      This sets the horizontal position of the text relative to the icon.
      Parameters:
      horizontalAlign - The horizontal text alignment relative to the icon which should be applied to the underlying component.
      Returns:
      This very builder to allow for method chaining.
      Throws:
      IllegalArgumentException - if horizontalAlign is null.
    • withHorizontalTextAlignment

      public final I withHorizontalTextAlignment(sprouts.Val<UI.HorizontalAlignment> horizontalAlign)
      A convenience method to avoid peeking into this builder like so:
      
           UI.button("Clickable!")
           .peek( button -> {
                property.onSetItem(v->button.setHorizontalTextPosition(v.forSwing()));
                button.setHorizontalTextPosition(property.get().forSwing());
           });
        
      This sets the horizontal position of the text relative to the icon and also binds the provided property to the underlying component.
      Hint: Use myProperty.fire(From.VIEW_MODEL) in your view model to send the property value to this view component.
      Parameters:
      horizontalAlign - The horizontal text alignment property relative to the icon which should be bound to the underlying component.
      Returns:
      This very builder to allow for method chaining.
      Throws:
      IllegalArgumentException - if horizontalAlign is null.
    • withVerticalTextAlignment

      public final I withVerticalTextAlignment(UI.VerticalAlignment verticalAlign)
      A convenience method to avoid peeking into this builder like so:
      
           UI.button("Clickable!")
               .peek( button -> button.setVerticalTextPosition(...) );
        
      This sets the vertical position of the text relative to the icon.
      Parameters:
      verticalAlign - The vertical text alignment relative to the icon which should be applied to the underlying component.
      Returns:
      This very builder to allow for method chaining.
      Throws:
      IllegalArgumentException - if verticalAlign is null.
    • withVerticalTextAlignment

      public final I withVerticalTextAlignment(sprouts.Val<UI.VerticalAlignment> verticalAlign)
      A convenience method to avoid peeking into this builder like so:
      
           UI.button("Clickable!")
           .peek( button -> {
                property.onSetItem(v->button.setVerticalTextPosition(v.forSwing()));
                button.setVerticalTextPosition(property.get().forSwing());
           });
        
      This sets the vertical position of the text relative to the icon and also binds the provided property to the underlying component.
      Hint: Use myProperty.fire(From.VIEW_MODEL) in your view model to send the property value to this view component.
      Parameters:
      verticalAlign - The vertical text alignment property relative to the icon which should be bound to the underlying component.
      Returns:
      This very builder to allow for method chaining.
      Throws:
      IllegalArgumentException - if verticalAlign is null.
    • withButtonGroup

      public final I withButtonGroup(ButtonGroup group)
      Use this to attach this button type to a button group.
      Parameters:
      group - The button group to which this button should be attached.
      Returns:
      This very builder to allow for method chaining.
    • withMargin

      public final I withMargin(Insets insets)
      Use this to set the margin of the wrapped button type.
      Parameters:
      insets - The margin of the button.
      Returns:
      This very builder to allow for method chaining.
    • withMargin

      public final I withMargin(int top, int left, int bottom, int right)
      Use this to set the margin of the wrapped button type.
      Parameters:
      top - The top margin of the button.
      left - The left margin of the button.
      bottom - The bottom margin of the button.
      right - The right margin of the button.
      Returns:
      This very builder to allow for method chaining.
    • getType

      public final Class<B> getType()
      The type class of the component managed by this builder. See documentation for method "build" for more information.
      Returns:
      The type class of the component managed by this builder.
    • getComponent

      @Deprecated public final B getComponent()
      Deprecated.
      Use get(Class) instead.
      The component managed by this builder.
      Returns:
      The component managed by this builder.
      Throws:
      IllegalStateException - if this method is called from a thread other than the EDT and this UI is configured to be decoupled from the application thread. See UIFactoryMethods.use(EventProcessor, Supplier).
    • component

      @Deprecated public final OptionalUI<B> component()
      Deprecated.
      Use get(Class) instead.
      The optional component managed by this builder.
      Returns:
      An OptionalUI wrapping a component or null. This optional will throw an exception if the application has an application thread (see UIFactoryMethods.use(EventProcessor, Supplier)) and this method is called from a thread other than the EDT.
    • peek

      public final I peek(Peeker<B> action)
      Use this if you wish to access the component wrapped by this builder directly. This is useful for more fine-grained control, like for example calling methods like "setName", "setTitle", and so on...
      This method accepts a lambda to which the component wrapped by this builder will be supplied. The lambda can then call said methods or perform other tasks which might be relevant to the component while also not breaking the benefits of nesting and method chaining provided by this class...
      The below example shows how this method allows for more fine-grained control over the wrapped component:
      
            UI.panel()
            peek( panel -> panel.setDebugGraphicsOptions(true) );
        


      Parameters:
      action - A Consumer lambda which simply returned the wrapped JComponent type for interacting it.
      Returns:
      This very instance, which enables builder-style method chaining.
    • applyIf

      public final I applyIf(boolean condition, Consumer<I> building)
      Use this to only build a certain part of the UI if the provided boolean condition is true. Which is to say, if the condition is false, then the second lambda is ignored, if on the other hand the condition is true, then the second lambda is executed with the current builder instance passed to it as a parameter. Inside the lambda, one can then continue building the UI while also not breaking the benefits of nesting and method chaining provided by this builder...

      This is in essence a more advanced version of apply(Consumer).
      Here a simple usage example:

      
          UI.panel()
          .applyIf( userIsLoggedIn, ui -> ui
            .add( UI.label("Welcome back!") )
            .add( UI.button("Logout")).onClick( () -> logout() )
            .add( UI.button("Settings")).onClick( () -> showSettings() )
          )
          .applyIf( !userIsLoggedIn, ui -> ui
            .add( UI.label("Please login to continue.") )
            .add( UI.button("Login")).onClick( () -> login() );
          );
        
      Here we use theis method to build a panel with different content depending on whether the user is logged in or not.

      Parameters:
      condition - The truth value which determines if the second consumer lambda is executed or not.
      building - A Consumer lambda which simply consumes this builder instance.
      Returns:
      This very instance, which enables builder-style method chaining.
    • applyIfPresent

      public final I applyIfPresent(Optional<Consumer<I>> building)
      Allows you to build declarative UI conditionally, meaning that the UI is only built if the provided Optional value is present. If the value is not present, meaning it is null, then the second lambda (containing UI declarations relevant to the value) is simply ignored.

      Consider the following example:

      
       // In your view model:
       public Optional<MySubModel> getM() {
         return Optional.ofNullable(this.model);
       }
      
       // In your view:
       UI.panel()
       .add(UI.label("Maybe Sub Model:"))
       .applyIfPresent(vm.getM().map(m->ui->ui
         .add(UI.label("Hello Sub Model!"))
         .add(UI.label("A:")
         .add(UI.textField(m.getA()))
         .add(UI.label("B:"))
         .add(UI.textField(m.getB()))
         // ...
       ))
       .add(UI.label("Some other stuff..."));
       
      The applyIfPresent method takes an Optional<Consumer<I>> as parameter, where I is the type of the UI builder. This allows you to map the optional value to a consumer which is only executed if the value is present. If the optional value is present, the consumer is executed with the current UI builder as a parameter, which allows you to continue building the UI as usual.
      The m->ui->ui may look a bit confusing at first, but it is simply a lambda expression which takes the optional value and returns a consumer (ui->ui... ) which takes the UI builder as a parameter.
      This is in essence a more advanced Optional centric version of applyIf(boolean, Consumer) and apply(Consumer).
      Parameters:
      building - An optional consumer lambda which simply consumes this builder node.
      Returns:
      This very instance, which enables builder-style method chaining.
    • apply

      public final I apply(Consumer<I> building)
      Use this to continue building UI inside a provided lambda if you need to introduce some imperative code in between the building process.
      This is especially useful for when you need to build UI based on loops. The current builder instance will simply be supplied to the provided Consumer lambda. Inside the supplied lambda, you can then continue building the UI while also not breaking the benefits of nesting and method chaining, effectively preserving the declarative nature of the builder.

      Here is a simple example of how this method can be used to build a panel with a variable amount of images displayed in a grid:
      
            UI.panel("wrap 3")
            .apply( ui -> {
                for ( String path : imagePaths )
                    ui.add( UI.label(UI.icon(path)) );
            });
        


      Here is another example of how this method can be used to build a panel with a variable amount of buttons displayed in a grid:
      
          UI.panel("wrap 4")
          .apply( ui -> {
            for ( int i = 0; i < numOfButtons; i++ )
                ui.add( UI.button("Button " + i)
                .onClick( () -> {...} );
          });
        


      Parameters:
      building - A Consumer lambda which simply consumes this builder instance.
      Returns:
      This very instance, which enables builder-style method chaining.
    • get

      public final B get(Class<B> type)
      This method completes the building process for the wrapped JComponent type by returning it. However, it also expects the user to pass the class of the JComponent wrapped by this builder! This is not out of necessity but for better readability when using the builder in more extensive ways where the beginning and end of the method chaining and nesting of the builder does not fit on one screen.
      In such cases the expression ".get(MyJComponent.class)" helps to identify which type of JComponent is currently being built on a given nesting layer...

      Here is a simple example that demonstrates this technique using a JPanel and a JMenuBar:
      
            UI.panel()
            .add(
                UI.menuBar()
                .add( UI.menu("File") )
                .add( UI.menuItem("Open") )
                .add( UI.menuItem("Save") )
                // ...
                .add( UI.menuItem("Exit") )
                .get(JMenuBar.class)
            )
            .add( UI.button("Click me!") )
            .get(JPanel.class);
        
      As you can see, the expression ".get(JMenuBar.class)" as well as the expression ".get(JPanel.class)" at the end of the builder chain help to identify which type of JComponent is currently being built and returned.
      Parameters:
      type - The type class of the component which this builder wraps.
      Returns:
      The result of the building process, namely: a type of JComponent.
    • add

      @SafeVarargs public final I add(JComponent... components)
      This builder class expects its implementations to be builder types for anything which can be built in a nested tree-like structure. Implementations of this abstract method ought to enable support for nested building.

      Parameters:
      components - An array of component instances which ought to be added to the wrapped component type.
      Returns:
      This very instance, which enables builder-style method chaining.
    • add

      public final <T extends JComponent> I add(UIForAnySwing<?,T> builder)
      Uses the supplied builder to build its component and then add it to the component that is being built by this builder instance. This directly allows you to nest your builder based UI declarations in an HTML-like fashion.
      Type Parameters:
      T - The type of the JComponent which is wrapped by the provided builder.
      Parameters:
      builder - A builder for another JComponent instance which ought to be added to the wrapped component type.
      Returns:
      This very instance, which enables builder-style method chaining.
    • add

      @SafeVarargs public final <B extends swingtree.UIForAnything<?, ?, JComponent>> I add(B... builders)
      This method provides the same functionality as the other "add" methods. However, it bypasses the necessity to call the "get" method by calling it internally for you.
      This helps to improve readability, especially when the degree of nesting is very low.
      Type Parameters:
      B - The type of the builder instances which are used to configure the components that will be added to the component wrapped by this builder.
      Parameters:
      builders - An array of builder instances whose JComponents ought to be added to the one wrapped by this builder.
      Returns:
      This very instance, which enables builder-style method chaining.
    • add

      public final I add(List<JComponent> components)
      This builder class expects its implementations to be builder types for anything which can be built in a nested tree-like structure. Implementations of this abstract method ought to enable support for nested building.

      Parameters:
      components - A list of component instances which ought to be added to the wrapped component type.
      Returns:
      This very instance, which enables builder-style method chaining.
    • _addBuildersTo

      @SafeVarargs protected final <B extends swingtree.UIForAnything<?, ?, JComponent>> void _addBuildersTo(B thisComponent, B... builders)
    • _addComponentsTo

      @SafeVarargs protected final void _addComponentsTo(B thisComponent, JComponent... componentsToBeAdded)
    • _addBuilderTo

      protected final void _addBuilderTo(B thisComponent, swingtree.UIForAnything<?,?,?> builder, @Nullable Object conf)
    • _state

      protected abstract swingtree.BuilderState<B> _state()
      Returns the state of the builder, which is a container for the wrapped component as well as it's type and current EventProcessor.
      Returns:
      The state of the builder.
    • _newBuilderWithState

      protected abstract swingtree.UIForAnything<I,B,JComponent> _newBuilderWithState(swingtree.BuilderState<B> newState)
      An internal wither method which creates a new builder instance with the provided BuilderState stored inside it.
      Parameters:
      newState - The new state which should be stored inside the new builder instance.
      Returns:
      A new builder instance with the provided state stored inside it.
    • _with

      protected final swingtree.UIForAnything<I,B,JComponent> _with(Consumer<B> componentMutator)
      Creates a new builder with the provided component mutation applied to the wrapped component.
      Note that the SwingTree builders are immutable, which means that this method does not mutate the current builder instance, but instead creates a new builder instance with a new BuilderState which contains the provided component mutation (see BuilderState.withMutator(Consumer)). Also see _newBuilderWithState(BuilderState).
      Parameters:
      componentMutator - A consumer lambda which receives the wrapped component and is then used to apply some builder action to it.
      Returns:
      A new builder instance with the provided component mutation applied to the wrapped component.
    • _runInUI

      protected final void _runInUI(Runnable action)
      A convenient shortcut to the EventProcessor.registerUIEvent(Runnable) method to the current EventProcessor attached to the current BuilderState. In practice, this method will ultimately just delegate tasks to the AWT Event Dispatch Thread (EDT).
      Parameters:
      action - An action which should be executed by the UI thread, which is determined by implementations of the EventProcessor, also see UIFactoryMethods.use(EventProcessor, Supplier).
      Usually the UI thread is AWT's Event Dispatch Thread (EDT).
    • _runInApp

      protected final void _runInApp(Runnable action)
      A convenient delegate to the EventProcessor.registerAppEvent(Runnable) method, which allows you to execute an action on the current application thread. To configure the current EventProcessor see UIFactoryMethods.use(EventProcessor, Supplier) or the underlying SwingTree.setEventProcessor(EventProcessor) method.
      Parameters:
      action - An action which should be executed by the application thread, which is determined by implementations of the current EventProcessor, also see UIFactoryMethods.use(EventProcessor, Supplier).
    • _runInApp

      protected final <T> void _runInApp(T value, Consumer<T> action)
      A convenient delegate to the EventProcessor.registerAppEvent(Runnable) method, which allows you to execute an action on the current application thread. Which thread executes these tasks is determined by the current EventProcessor. Usually this is the EventProcessor.COUPLED or EventProcessor.COUPLED_STRICT event processor.
      Type Parameters:
      T - The type of the value.
      Parameters:
      value - A value which should be captured and then passed to the provided action on the current application thread (see EventProcessor and UIFactoryMethods.use(EventProcessor, Supplier)).
      action - A consumer lambda which is executed by the application thread and receives the provided value.
    • _onShow

      protected final <T> void _onShow(sprouts.Val<T> val, B thisComponent, BiConsumer<B,T> displayAction)
      Use this to register a state change listener for the provided property which will be executed by the UI thread (see EventProcessor).
      Type Parameters:
      T - The type of the item wrapped by the provided property.
      Parameters:
      val - A property whose state changes should be listened to on the UI thread.
      thisComponent - The component which is wrapped by this builder.
      displayAction - A consumer lambda receiving the provided value and is then executed by the UI thread.
    • _withOnShow

      protected final <T> swingtree.UIForAnything<I,B,JComponent> _withOnShow(sprouts.Val<T> val, BiConsumer<B,T> displayAction)
    • _onShow

      protected final <T> void _onShow(sprouts.Vals<T> vals, B c, BiConsumer<B,sprouts.ValsDelegate<T>> displayAction)
      Use this to register a state change listener for the provided property list which will be executed by the UI thread (see EventProcessor).
      Type Parameters:
      T - The type of the items wrapped by the provided property list.
      Parameters:
      vals - A property list whose state changes should be listened to on the UI thread.
      c - The component which is wrapped by this builder.
      displayAction - A consumer lambda receiving the action delegate and is then executed by the UI thread.
    • _withOnShow

      protected final <T> swingtree.UIForAnything<I,B,JComponent> _withOnShow(sprouts.Vals<T> vals, BiConsumer<B,sprouts.ValsDelegate<T>> displayAction)
    • _this

      protected final I _this()
      Exposes the this-pointer of the builder instance cast to the I type parameter of the builder class.
      This is done to reduce the amount of type casting and warnings in the codebase.
      Returns:
      The builder instance itself based on the type parameter <I>.
    • _disposeState

      protected final void _disposeState()
      This method is used to dispose of the state of the builder, which means that the builder state disposes of its reference to either the wrapped component or the wrapped component or the composite of component factories which are used to build the wrapped component eagerly each time the wrapped component is accessed.
      This is important to avoid memory leaks, as a component is typically part of a tree of components, and if one component is not garbage collected, then the whole tree is not garbage collected.
    • hashCode

      public final int hashCode()
      Overrides:
      hashCode in class Object
    • equals

      public final boolean equals(Object obj)
      Overrides:
      equals in class Object
    • toString

      public final String toString()
      Overrides:
      toString in class Object