Package swingtree.style
Class StyleSheet
java.lang.Object
swingtree.style.StyleSheet
An abstract class intended to be extended to create custom CSS look-alike
source code based style sheets for your Swing application.
Note that the
The intended way to use a
A style sheet object is in essence merely a collection of
StyleTraits and corresponding Styler lambdas
which are used by the SwingTree style engine
to calculate component StyleConf configurations
in a functional and side effect free manner.
Implement the configure() method and
use the add(StyleTrait, Styler) method to
add StyleTraits and corresponding Styler lambdas
to the style sheet.
There are also various factory methods for creating StyleTraits
in the form of id(String), group(String), group(Enum), type(Class).
This is designed to make your style sheet code more readable and maintainable.
Here an example of how this class is
typically used to create a custom style sheet:
class MyStyleSheet extends StyleSheet {
{@literal @}Override
protected void configure() {
add(group("MyButton"), it -> it
.margin(12)
.padding(16)
.backgroundColor(Color.YELLOW)
);
add(type(JLabel.class).id("Foo"), it-> it
.borderRadius(5)
.gradient("Bar", ... )
);
add(group(Group.ERROR), it -> it
.backgroundColor(Color.RED)
.borderColor(Color.YELLOW)
.borderWidth(2)
);
}
}
This API design is inspired by the CSS styling language, and the use of immutable objects
is a key feature of the style API, which makes it possible to safely compose
Styler lambdas into any kind of style inheritance hierarchy
without having to worry about side effects.
Note that the
configure() method, here the Styler lambdas
are intended to be registered, is not called eagerly in the constructor of the style sheet,
but rather lazily when the style sheet is first used to calculate
the style configuration for a particular component, which happens through the
computeStyleFrom(JComponent) or computeStyleFrom(JComponent, StyleConf) methods.
The intended way to use a
StyleSheet is by configuring it globally
through SwingTree.initialiseUsing(SwingTreeConfigurator), or if
you want to apply ste sheets to specific scopes through UIFactoryMethods.use(StyleSheet, Supplier).
The second argument is a supplier lambda for your SwingTree GUI declaration where each component
will be bound to the StyleSheet you supplied!-
Field Summary
Fields -
Constructor Summary
ConstructorsModifierConstructorDescriptionprotectedprotectedStyleSheet(StyleSheet parentStyleSheet) Use this method to inherit styles from the suppliedparentStyleSheet. -
Method Summary
Modifier and TypeMethodDescriptionprotected <C extends JComponent>
voidadd(StyleTrait<C> trait, Styler<C> traitStyler) Use this to register style rules in youconfigure()implementation by providing aStyleTraittargeting the components you want to style (seeid(String),group(String),group(Enum),type(Class)), and a correspondingStylerlambda which will be applied to the components targeted by theStyleTrait.final StyleConfcomputeStyleFrom(JComponent toBeStyled) Uses this style sheet to compute theStyleConffor a component derived from theStyleConf.none()constant as a basis.final StyleConfcomputeStyleFrom(JComponent toBeStyled, StyleConf startingStyle) protected abstract voidOverride this method to configure the style sheet by addingStyleTraits and correspondingStylerlambdas to the style sheet through theadd(StyleTrait, Styler)method.protected <E extends Enum<E>>
StyleTrait<JComponent> group(E group) A factory method for aStyleTraittargeting components belonging to the given enum group (seeUIForAnySwing.group(Enum...).protected StyleTrait<JComponent> A factory method for aStyleTraittargeting components belonging to the given string group (seeUIForAnySwing.group(String...).protected StyleTrait<JComponent> A factory method for aStyleTraittargeting components with the given id/name (seeComponent.setName(String)).static StyleSheetnone()A factory method for getting the empty style sheet representing no style whatsoever.final sprouts.ObservableCreates and returns anObservableon an internalEventwhich is triggered after every time thisStyleSheetis being configured through theconfigure()method.
Components created from SwingTree use this observable to recompute and apply their style from this style sheet...
Note that the instance returned by this method is weakly referenced by the sourceEvent.final voidEssentially (re)initiates the style sheet by clearing all previously registeredStyleTraits andStylers, and then calling theconfigure()method again to establish a potentially completely new style.
You can use this method to build highly dynamic styling behavior.protected <C extends JComponent>
StyleTrait<C> A factory method for aStyleTraittargeting components which are of a given type (seeObject.getClass().
-
Field Details
-
log
protected final org.slf4j.Logger log
-
-
Constructor Details
-
StyleSheet
protected StyleSheet() -
StyleSheet
Use this method to inherit styles from the suppliedparentStyleSheet. All styles in the parent will be reused in this style, but you may overwrite parent styles in the localconfigure()method...- Parameters:
parentStyleSheet- AnotherStyleSheetfrom which this one should inherit all styles!
-
-
Method Details
-
none
A factory method for getting the empty style sheet representing no style whatsoever. It is especially useful instead of null.- Returns:
- A style sheet without any traits and stylers.
-
observable
public final sprouts.Observable observable()Creates and returns anObservableon an internalEventwhich is triggered after every time thisStyleSheetis being configured through theconfigure()method.
Components created from SwingTree use this observable to recompute and apply their style from this style sheet...
Note that the instance returned by this method is weakly referenced by the sourceEvent. This means that when a call-site no longer holds on to their observer, then it will be garbage collected alongside all of theObserver(event listeners) registered on it!- Returns:
- A weakly referenced
Observablewhich can be used to react toStyleSheetre-configurations...
-
reconfigure
public final void reconfigure()Essentially (re)initiates the style sheet by clearing all previously registeredStyleTraits andStylers, and then calling theconfigure()method again to establish a potentially completely new style.
You can use this method to build highly dynamic styling behavior. For example, during the new configuration you may want to add switch to a completely a different set of traits with differentStylers depending on the current theme of the application, which you also want the user to change at runtime (but don't forget to repaint the components to see the effect). -
id
A factory method for aStyleTraittargeting components with the given id/name (seeComponent.setName(String)). This is intended to be used in theconfigure()method of the style sheet. Note that this method does not set the id/name of the component, it expects there to be a component with the given id/name already in the component hierarchy so that a correspondingStylerlambda can be applied to it.
This is intended to be used in theconfigure()method of the style sheet.
Here an example of how to use this method in theconfigure()method:add(id("myButton"), it -> it.backgroundColor(Color.CYAN));- Parameters:
id- The id/name of the component to target.- Returns:
- A
StyleTraittargeting components with the given id/name.
-
group
A factory method for aStyleTraittargeting components belonging to the given string group (seeUIForAnySwing.group(String...). A group is conceptually similar to a CSS class, meaning that you can add a group to any component and then target all components belonging to that group with a singleStyleTrait. Note that this method does not add the group to any component, it expects there to be a component with the given group already in the component hierarchy so that a correspondingStylerlambda can be applied to it.
This is intended to be used in theconfigure()method of the style sheet.
Here an example of how to use this method in theconfigure()method:
Although usingadd(group("myGroup"), it -> it.backgroundColor(Color.RED));Strings is a convenient way of grouping components, it is not ideal with respect to compile time safety. Please usegroup(Enum)andUIForAnySwing.group(Enum[])instead...- Parameters:
group- The group to target in the form of a string.- Returns:
- A
StyleTraittargeting components belonging to the given group.
-
group
A factory method for aStyleTraittargeting components belonging to the given enum group (seeUIForAnySwing.group(Enum...). A group is conceptually similar to a CSS class, meaning that you can add a group to any component and then target all components belonging to that group with a singleStyleTrait. Note that this method does not add the group to any component, it expects there to be a component with the given group already in the component hierarchy so that a correspondingStylerlambda can be applied to it.
This is intended to be used in theconfigure()method of the style sheet.
Here an example of how to use this method in theconfigure()method:add(group(Group.ERROR), it -> it.backgroundColor(Color.RED));- Type Parameters:
E- The type of the enum defining the group to target.- Parameters:
group- The group to target in the form of an enum.- Returns:
- A
StyleTraittargeting components belonging to the given group.
-
type
A factory method for aStyleTraittargeting components which are of a given type (seeObject.getClass(). Note that this method does not set the type of any component, it expects there to be a component of the given type already in the component hierarchy so that a correspondingStylerlambda can be applied to it.
This is intended to be used in theconfigure()method of the style sheet.
Here an example of how to use this method in theconfigure()method:add(type(JButton.class), it -> it.backgroundColor(Color.RED));- Type Parameters:
C- The type of the components to target for styling.- Parameters:
type- The type of the component to target.- Returns:
- A
StyleTraittargeting components of the given type.
-
add
Use this to register style rules in youconfigure()implementation by providing aStyleTraittargeting the components you want to style (seeid(String),group(String),group(Enum),type(Class)), and a correspondingStylerlambda which will be applied to the components targeted by theStyleTrait.
Here an example of how to use this method in theconfigure()method:@Override protected void configure() { add(id("arial-button"), it -> it.font(new Font("Arial", Font.BOLD, 12))); add(type(JButton).group("FooBar"), it -> it.borderRadius(5)); add(group(Group.ERROR), it -> it.backgroundColor(Color.RED)); // ... }- Type Parameters:
C- The type of the components targeted by theStyleTrait.- Parameters:
trait- TheStyleTraittargeting the components you want to style.traitStyler- TheStylerlambda which will be applied to the components targeted by theStyleTrait.
-
configure
protected abstract void configure()Override this method to configure the style sheet by addingStyleTraits and correspondingStylerlambdas to the style sheet through theadd(StyleTrait, Styler)method.
Example:@Override protected void configure() { add(type(JComponent.class), it -> it .backgroundColor(new Color(0.7f, 0.85f, 1f)) .padding(4) .margin(5) ); add(type(JButton.class), it -> it .padding(12) .margin(16) .gradient("default", shade -> shade .strategy(ShadingStrategy.TOP_LEFT_TO_BOTTOM_RIGHT) .colors(it.component().getBackground().brighter(), Color.CYAN) ) ); // ... } -
computeStyleFrom
Uses this style sheet to compute theStyleConffor a component derived from theStyleConf.none()constant as a basis. Note that the style sheet is expected to already be configured at this point, because theconfigure()method is called in the constructor of the style sheet.
Example:
Note that this method does NOT install the style on the supplied component! Style installation is intended to happen when you SwingTree UI declarations are bound to a particularMyStyleSheet styleSheet = new MyStyleSheet(); JComboBox<String> comboBox = new JComboBox<>(); var style = styleSheet.computeStyleFrom(comboBox);StyleSheetthrough theUIFactoryMethods.use(StyleSheet, Supplier)method.- Parameters:
toBeStyled- The component to apply the style sheet to.- Returns:
- The
StyleConfthat was applied to the component.
-
computeStyleFrom
Uses this style sheet to compute theStyleConffor a component derived from the suppliedStyleConfas a basis. Note that the style sheet must already be configured at this point, because theconfigure()method needs to be called before in the constructor of the style sheet to bei able to compute the style.Example:
Note that this method does NOT install the style on the supplied component! Style installation is intended to happen when you SwingTree UI declarations are bound to a particularMyStyleSheet styleSheet = new MyStyleSheet(); JComboBox<String> comboBox = new JComboBox<>(); var style = styleSheet.computeStyleFrom(comboBox, Style.none());StyleSheetthrough theUIFactoryMethods.use(StyleSheet, Supplier)method.- Parameters:
toBeStyled- The component for which a style ought to be computed and returned.startingStyle- TheStyleConfto start with when applying the style sheet.- Returns:
- The
StyleConfthat was applied to the component. - Throws:
NullPointerException- If either argument is null.
-