SwingTreeInitConfig.java
- package swingtree;
- import org.jspecify.annotations.Nullable;
- import swingtree.style.StyleSheet;
- import swingtree.threading.EventProcessor;
- import java.awt.Font;
- import java.util.Objects;
- import java.util.Optional;
- import java.util.function.Supplier;
- /**
- * An immutable configuration object for the {@link SwingTree} library,
- * which can be configured using a functional {@link SwingTreeConfigurator} lambda
- * passed to {@link SwingTree#initialiseUsing(SwingTreeConfigurator)}.
- * <p>
- * It allows for the configuration of the default
- * font, font installation, scaling, event processing and
- * application wide {@link StyleSheet}.
- */
- public final class SwingTreeInitConfig
- {
- /**
- * Defines how the {@link Font}, specified through {@link SwingTreeInitConfig#defaultFont(Font)},
- * is installed in the {@link javax.swing.UIManager}.
- */
- public enum FontInstallation
- {
- /**
- * A soft installation will only install the font as the "defaultFont" property
- * of the {@link javax.swing.UIManager}.
- */
- SOFT,
- /**
- * A hard installation will install the font as the "defaultFont" property
- * of the {@link javax.swing.UIManager} and as the default font of all
- * {@link javax.swing.UIManager} components.
- */
- HARD,
- /**
- * No installation will be performed.
- */
- NONE
- }
- /**
- * Defines how the scaling factor for the UI should be determined.
- */
- public enum Scaling
- {
- /**
- * No scaling will be performed.
- */
- NONE,
- /**
- * The scaling will be derived from the supplied scaling factor.
- * (see {@link SwingTreeInitConfig#uiScaleFactor(float)} as well as
- * system property {@code "swingtree.uiScale"}).
- */
- FROM_SCALING_FACTOR,
- /**
- * The scaling will be derived from the default font size,
- * if a default font was specified. (see {@link SwingTreeInitConfig#defaultFont(Font)})
- */
- FROM_DEFAULT_FONT,
- /**
- * The scaling will be derived from the system font size.
- * This scaling policy is chosen if no default font was specified,
- * no scaling factor was specified and the scaling mode is enabled
- * (see {@link SwingTreeInitConfig#isUiScaleFactorEnabled()}).
- */
- FROM_SYSTEM_FONT
- }
- public static SwingTreeInitConfig standard() {
- return new SwingTreeInitConfig(
- null,
- FontInstallation.SOFT,
- EventProcessor.COUPLED_STRICT,
- StyleSheet.none(),
- SystemProperties.getFloat(SystemProperties.UI_SCALE, -1 ),
- SystemProperties.getBool(SystemProperties.UI_SCALE_ENABLED, true ),
- SystemProperties.getBool(SystemProperties.UI_SCALE_ALLOW_SCALE_DOWN, false ),
- SystemProperties.getLong(SystemProperties.ANIMATION_INTERVAL, 16 )
- );
- /*
- Note that we want the refresh rate to be as high as possible so that the animation
- looks smooth, but we don't want to use 100% of the CPU.
- The ideal refresh rate is 60 fps which is 16.6 ms per frame.
- So we set the timer to 16 ms.
- This does of course not account for the time it takes to run the animation
- code, but that should be negligible, and in the worst case
- the animation will be a bit slower than 60 fps.
- */
- }
- private final @Nullable Font _defaultFont; // may be null
- private final FontInstallation _fontInstallation;
- private final EventProcessor _eventProcessor;
- private final StyleSheet _styleSheet;
- private final float _uiScale;
- private final boolean _uiScaleEnabled;
- private final boolean _uiScaleAllowScaleDown;
- private final long _defaultAnimationInterval;
- private SwingTreeInitConfig(
- @Nullable Font defaultFont,
- FontInstallation fontInstallation,
- EventProcessor eventProcessor,
- StyleSheet styleSheet,
- float uiScale,
- boolean uiScaleEnabled,
- boolean uiScaleAllowScaleDown,
- long defaultAnimationInterval
- ) {
- _defaultFont = defaultFont;
- _fontInstallation = Objects.requireNonNull(fontInstallation);
- _eventProcessor = Objects.requireNonNull(eventProcessor);
- _styleSheet = Objects.requireNonNull(styleSheet);
- _uiScale = uiScale;
- _uiScaleEnabled = uiScaleEnabled;
- _uiScaleAllowScaleDown = uiScaleAllowScaleDown;
- _defaultAnimationInterval = defaultAnimationInterval;
- }
- /**
- * Returns an {@link Optional} containing the default font
- * or an empty {@link Optional} if no default font is set.
- */
- Optional<Font> defaultFont() {
- return Optional.ofNullable(_defaultFont);
- }
- /**
- * Returns the {@link FontInstallation} mode.
- */
- FontInstallation fontInstallation() {
- return _fontInstallation;
- }
- /**
- * Returns the {@link Scaling} mode
- * which is determined based on the configuration.
- * <ul>
- * <li>
- * If {@code false} was passed to {@link #isUiScaleFactorEnabled(boolean)},
- * then {@link Scaling#NONE} is returned.
- * </li>
- * <li>
- * Otherwise, if a scaling factor greater than 0 was passed to {@link #uiScaleFactor(float)},
- * then {@link Scaling#FROM_SCALING_FACTOR} is returned.
- * </li>
- * <li>
- * Otherwise, if a default font was passed to {@link #defaultFont(Font)}, <br>
- * then {@link Scaling#FROM_DEFAULT_FONT} is returned. <br>
- * </li>
- * </ul>
- * <p>
- * If none of the above applies, then {@link Scaling#FROM_SYSTEM_FONT} is returned. <br>
- */
- Scaling scalingStrategy() {
- if ( !_uiScaleEnabled )
- return Scaling.NONE;
- if ( _uiScale > 0 )
- return Scaling.FROM_SCALING_FACTOR;
- if ( _defaultFont != null )
- return Scaling.FROM_DEFAULT_FONT;
- return Scaling.FROM_SYSTEM_FONT;
- }
- /**
- * Returns the {@link EventProcessor},
- * which is used to process both UI and application events.
- */
- EventProcessor eventProcessor() {
- return _eventProcessor;
- }
- /**
- * Returns an {@link Optional} containing the {@link StyleSheet}
- * or an empty {@link Optional} if no {@link StyleSheet} is set.
- */
- StyleSheet styleSheet() {
- return _styleSheet;
- }
- /**
- * Returns the UI scaling factor as is specified by the system property {@code swingtree.uiScale}.
- */
- float uiScaleFactor() {
- return _uiScale;
- }
- /**
- * Returns whether the UI scaling mode is enabled as is specified by the system property {@code swingtree.uiScale.enabled}.
- */
- boolean isUiScaleFactorEnabled() {
- return _uiScaleEnabled;
- }
- /**
- * Returns whether values smaller than 100% are allowed for the user scale factor
- * as is specified by the system property {@code swingtree.uiScale.allowScaleDown}.
- */
- boolean isUiScaleDownAllowed() {
- return _uiScaleAllowScaleDown;
- }
- /**
- * Returns the default animation interval in milliseconds,
- * which is a property that
- * determines the delay between two consecutive animation steps.
- * You can think of it as the time between the heartbeats of the animation.
- * The smaller the interval, the higher the refresh rate and
- * the smoother the animation will look.
- * However, the smaller the interval, the more CPU time will be used.
- * The default interval is 16 ms which corresponds to 60 fps.
- * See {@link #standard()}, returning an instance of this config with the default value. <br>
- * This property is used as default value by the {@link swingtree.animation.LifeTime}
- * object which is used to define the duration of an {@link swingtree.animation.Animation}.
- */
- long defaultAnimationInterval() {
- return _defaultAnimationInterval;
- }
- /**
- * Used to configure the default font, which may be used by the {@link SwingTree}
- * to derive the UI scaling factor and or to install the font in the {@link javax.swing.UIManager}
- * depending on the {@link FontInstallation} mode (see {@link #defaultFont(Font, FontInstallation)}).
- * @param newDefaultFont The new default font, or {@code null} to unset the default font.
- * @return A new {@link SwingTreeInitConfig} instance with the new default font.
- */
- public SwingTreeInitConfig defaultFont( Font newDefaultFont ) {
- return new SwingTreeInitConfig(newDefaultFont, _fontInstallation, _eventProcessor, _styleSheet, _uiScale, _uiScaleEnabled, _uiScaleAllowScaleDown, _defaultAnimationInterval);
- }
- /**
- * Used to configure both the default {@link Font} and the {@link FontInstallation} mode.
- * <p>
- * The {@link FontInstallation} mode determines how the {@link Font} is installed
- * in the {@link javax.swing.UIManager} (see {@link FontInstallation}).
- * <p>
- * If the {@link FontInstallation} mode is {@link FontInstallation#SOFT},
- * then the {@link Font} will only be installed as the "defaultFont" property
- * in the {@link javax.swing.UIManager}. If on the other hand the {@link FontInstallation}
- * mode is {@link FontInstallation#HARD}, then the {@link Font} will be installed
- * by replacing all {@link Font}s in the {@link javax.swing.UIManager}.
- *
- * @param newDefaultFont The new default font, or {@code null} to unset the default font.
- * @param newFontInstallation The new {@link FontInstallation} mode.
- * @return A new {@link SwingTreeInitConfig} instance with the new default font and {@link FontInstallation} mode.
- */
- public SwingTreeInitConfig defaultFont( Font newDefaultFont, FontInstallation newFontInstallation ) {
- return new SwingTreeInitConfig(newDefaultFont, newFontInstallation, _eventProcessor, _styleSheet, _uiScale, _uiScaleEnabled, _uiScaleAllowScaleDown, _defaultAnimationInterval);
- }
- /**
- * Used to configure the {@link EventProcessor}, which is used to process both
- * UI and application events.
- * You may create your own {@link EventProcessor} implementation or use one of the
- * predefined ones like {@link EventProcessor#COUPLED_STRICT}, {@link EventProcessor#COUPLED}
- * or {@link EventProcessor#DECOUPLED}.
- *
- * @param newEventProcessor The new {@link EventProcessor}.
- * @return A new {@link SwingTreeInitConfig} instance with the new {@link EventProcessor}.
- */
- public SwingTreeInitConfig eventProcessor( EventProcessor newEventProcessor ) {
- return new SwingTreeInitConfig(_defaultFont, _fontInstallation, newEventProcessor, _styleSheet, _uiScale, _uiScaleEnabled, _uiScaleAllowScaleDown, _defaultAnimationInterval);
- }
- /**
- * Used to configure a global {@link StyleSheet} serving as a base for all
- * {@link StyleSheet}s used inside your application (see {@link UI#use(swingtree.style.StyleSheet, Supplier)}).
- *
- * @param newStyleSheet The new {@link StyleSheet}, or {@code null} to unset the {@link StyleSheet}.
- * @return A new {@link SwingTreeInitConfig} instance with the new {@link StyleSheet}.
- */
- public SwingTreeInitConfig styleSheet( StyleSheet newStyleSheet ) {
- return new SwingTreeInitConfig(_defaultFont, _fontInstallation, _eventProcessor, newStyleSheet, _uiScale, _uiScaleEnabled, _uiScaleAllowScaleDown, _defaultAnimationInterval);
- }
- /**
- * Use this to configure the UI scaling factor.
- * The default factor determined by the system property {@code "swingtree.uiScale"}.
- * <p>
- * If Java runtime scales (Java 9 or later), this scale factor is applied on top
- * of the Java system scale factor. Java 8 does not scale and this scale factor
- * replaces the user scale factor that SwingTree computes based on the font.
- * To replace the Java 9+ system scale factor, use system property "sun.java2d.uiScale",
- * which has the same syntax as this one.
- * <p>
- * <strong>Allowed Values</strong> e.g. {@code 1.5}, {@code 1.5x}, {@code 150%} or {@code 144dpi} (96dpi is 100%)<br>
- *
- * @param newUiScale The new UI scaling factor.
- * @return A new {@link SwingTreeInitConfig} instance with the new UI scaling factor.
- */
- public SwingTreeInitConfig uiScaleFactor( float newUiScale ) {
- return new SwingTreeInitConfig(_defaultFont, _fontInstallation, _eventProcessor, _styleSheet, newUiScale, _uiScaleEnabled, _uiScaleAllowScaleDown, _defaultAnimationInterval);
- }
- /**
- * Used to configure whether the UI scaling mode is enabled as is specified by the
- * system property {@code swingtree.uiScale.enabled}.
- * <p>
- * <strong>Allowed Values</strong> {@code false} and {@code true}<br>
- * <strong>Default</strong> {@code true}
- *
- * @param newUiScaleEnabled The new UI scaling mode.
- * @return A new {@link SwingTreeInitConfig} instance with the new UI scaling mode.
- */
- public SwingTreeInitConfig isUiScaleFactorEnabled( boolean newUiScaleEnabled ) {
- return new SwingTreeInitConfig(_defaultFont, _fontInstallation, _eventProcessor, _styleSheet, _uiScale, newUiScaleEnabled, _uiScaleAllowScaleDown, _defaultAnimationInterval);
- }
- /**
- * Used to configure whether values smaller than 100% are allowed for the user scale factor
- * as is specified by the system property {@code swingtree.uiScale.allowScaleDown}.
- * <p>
- * <strong>Allowed Values</strong> {@code false} and {@code true}<br>
- * <strong>Default</strong> {@code false}
- *
- * @param newUiScaleAllowScaleDown The new UI scaling mode.
- * @return A new {@link SwingTreeInitConfig} instance with the new UI scaling mode.
- */
- public SwingTreeInitConfig isUiScaleDownAllowed( boolean newUiScaleAllowScaleDown ) {
- return new SwingTreeInitConfig(_defaultFont, _fontInstallation, _eventProcessor, _styleSheet, _uiScale, _uiScaleEnabled, newUiScaleAllowScaleDown, _defaultAnimationInterval);
- }
- /**
- * Used to configure the default animation interval in milliseconds,
- * which is a property that
- * determines the delay between two consecutive animation steps.
- * You can think of it as the time between the heartbeats of the animation.
- * The smaller the interval, the higher the refresh rate and
- * the smoother the animation will look.
- * However, the smaller the interval, the more CPU time will be used.
- * The default interval is 16 ms which corresponds to 60 fps.
- * See {@link #standard()}, returning an instance of this config with the default value. <br>
- * This property is used as default value by the {@link swingtree.animation.LifeTime}
- * object which is used to define the duration of an {@link swingtree.animation.Animation}.
- *
- * @param newDefaultAnimationInterval The new default animation interval.
- * @return A new {@link SwingTreeInitConfig} instance with the new default animation interval.
- */
- public SwingTreeInitConfig defaultAnimationInterval( long newDefaultAnimationInterval ) {
- return new SwingTreeInitConfig(_defaultFont, _fontInstallation, _eventProcessor, _styleSheet, _uiScale, _uiScaleEnabled, _uiScaleAllowScaleDown, newDefaultAnimationInterval);
- }
- /**
- * Defines/documents own system properties used in SwingTree.
- *
- * @author Daniel Nepp, but originally a derivative work of Karl Tauber
- */
- private static interface SystemProperties
- {
- /**
- * Specifies a custom scale factor used to scale the UI.
- * <p>
- * If Java runtime scales (Java 9 or later), this scale factor is applied on top
- * of the Java system scale factor. Java 8 does not scale and this scale factor
- * replaces the user scale factor that SwingTree computes based on the font.
- * To replace the Java 9+ system scale factor, use system property "sun.java2d.uiScale",
- * which has the same syntax as this one.
- * <p>
- * <strong>Allowed Values</strong> e.g. {@code 1.5}, {@code 1.5x}, {@code 150%} or {@code 144dpi} (96dpi is 100%)<br>
- */
- String UI_SCALE = "swingtree.uiScale";
- /**
- * Specifies whether user scaling mode is enabled.
- * <p>
- * <strong>Allowed Values</strong> {@code false} and {@code true}<br>
- * <strong>Default</strong> {@code true}
- */
- String UI_SCALE_ENABLED = "swingtree.uiScale.enabled";
- /**
- * Specifies whether values smaller than 100% are allowed for the user scale factor
- * (see {@link UI#scale()}).
- * <p>
- * <strong>Allowed Values</strong> {@code false} and {@code true}<br>
- * <strong>Default</strong> {@code false}
- */
- String UI_SCALE_ALLOW_SCALE_DOWN = "swingtree.uiScale.allowScaleDown";
- /**
- * Specifies the default animation interval in milliseconds.
- * <p>
- * This property is used as default value by the {@link swingtree.animation.LifeTime}
- * object which is used to define the duration of an {@link swingtree.animation.Animation}.
- * <p>
- * <strong>Allowed Values</strong> must be a positive integer<br>
- * <strong>Default</strong> {@code 16}
- */
- String ANIMATION_INTERVAL = "swingtree.animationInterval";
- /**
- * Checks whether a system property is set and returns {@code true} if its value
- * is {@code "true"} (case-insensitive), otherwise it returns {@code false}.
- * If the system property is not set, {@code defaultValue} is returned.
- */
- static boolean getBool( String key, boolean defaultValue ) {
- String value = System.getProperty( key );
- return (value != null) ? Boolean.parseBoolean( value ) : defaultValue;
- }
- /**
- * Similar to sun.java2d.SunGraphicsEnvironment.getScaleFactor(String)
- */
- static float getFloat( String key, float defaultValue ) {
- String s = System.getProperty( key );
- if ( s == null )
- return defaultValue;
- float units = 1;
- if ( s.endsWith( "x" ) )
- s = s.substring( 0, s.length() - 1 );
- else if ( s.endsWith( "dpi" ) ) {
- units = 96;
- s = s.substring( 0, s.length() - 3 );
- } else if ( s.endsWith( "%" ) ) {
- units = 100;
- s = s.substring( 0, s.length() - 1 );
- }
- try {
- float scale = Float.parseFloat( s );
- return scale > 0 ? scale / units : -1;
- } catch( NumberFormatException ex ) {
- return defaultValue;
- }
- }
- static long getLong( String key, long defaultValue ) {
- String s = System.getProperty( key );
- if ( s == null )
- return defaultValue;
- try {
- long interval = Long.parseLong( s );
- return interval > 0 ? interval : defaultValue;
- } catch( NumberFormatException ex ) {
- return defaultValue;
- }
- }
- }
- }