mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2025-12-06 05:50:53 +03:00
UIDefaultsLoader: added systemColor() color function that can be used to change accent color (preparation for getting accent color from operating system)
This commit is contained in:
@@ -98,6 +98,7 @@ public abstract class FlatLaf
|
||||
private static List<Object> customDefaultsSources;
|
||||
private static Map<String, String> globalExtraDefaults;
|
||||
private Map<String, String> extraDefaults;
|
||||
private static Function<String, Color> systemColorGetter;
|
||||
|
||||
private String desktopPropertyName;
|
||||
private String desktopPropertyName2;
|
||||
@@ -897,14 +898,14 @@ public abstract class FlatLaf
|
||||
* E.g. using {@link UIManager#setLookAndFeel(LookAndFeel)} or {@link #setup(LookAndFeel)}.
|
||||
* <p>
|
||||
* The global extra defaults are useful for smaller additional defaults that may change.
|
||||
* E.g. accent color. Otherwise, FlatLaf properties files should be used.
|
||||
* Otherwise, FlatLaf properties files should be used.
|
||||
* See {@link #registerCustomDefaultsSource(String)}.
|
||||
* <p>
|
||||
* The keys and values are strings in same format as in FlatLaf properties files.
|
||||
* <p>
|
||||
* Sample that setups "FlatLaf Light" theme with red accent color:
|
||||
* Sample that setups "FlatLaf Light" theme with white background color:
|
||||
* <pre>{@code
|
||||
* FlatLaf.setGlobalExtraDefaults( Collections.singletonMap( "@accentColor", "#f00" ) );
|
||||
* FlatLaf.setGlobalExtraDefaults( Collections.singletonMap( "@background", "#fff" ) );
|
||||
* FlatLightLaf.setup();
|
||||
* }</pre>
|
||||
*
|
||||
@@ -929,15 +930,15 @@ public abstract class FlatLaf
|
||||
* E.g. using {@link UIManager#setLookAndFeel(LookAndFeel)} or {@link #setup(LookAndFeel)}.
|
||||
* <p>
|
||||
* The extra defaults are useful for smaller additional defaults that may change.
|
||||
* E.g. accent color. Otherwise, FlatLaf properties files should be used.
|
||||
* Otherwise, FlatLaf properties files should be used.
|
||||
* See {@link #registerCustomDefaultsSource(String)}.
|
||||
* <p>
|
||||
* The keys and values are strings in same format as in FlatLaf properties files.
|
||||
* <p>
|
||||
* Sample that setups "FlatLaf Light" theme with red accent color:
|
||||
* Sample that setups "FlatLaf Light" theme with white background color:
|
||||
* <pre>{@code
|
||||
* FlatLaf laf = new FlatLightLaf();
|
||||
* laf.setExtraDefaults( Collections.singletonMap( "@accentColor", "#f00" ) );
|
||||
* laf.setExtraDefaults( Collections.singletonMap( "@background", "#fff" ) );
|
||||
* FlatLaf.setup( laf );
|
||||
* }</pre>
|
||||
*
|
||||
@@ -979,6 +980,36 @@ public abstract class FlatLaf
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the system color getter function, or {@code null}.
|
||||
*
|
||||
* @since 3
|
||||
*/
|
||||
public static Function<String, Color> getSystemColorGetter() {
|
||||
return systemColorGetter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a system color getter function that is invoked when function
|
||||
* {@code systemColor()} is used in FlatLaf properties files.
|
||||
* <p>
|
||||
* The name of the system color is passed as parameter to the function.
|
||||
* The function should return {@code null} for unknown system colors.
|
||||
* <p>
|
||||
* Can be used to change the accent color:
|
||||
* <pre>{@code
|
||||
* FlatLaf.setSystemColorGetter( name -> {
|
||||
* return name.equals( "accent" ) ? Color.red : null;
|
||||
* } );
|
||||
* FlatLightLaf.setup();
|
||||
* }</pre>
|
||||
*
|
||||
* @since 3
|
||||
*/
|
||||
public static void setSystemColorGetter( Function<String, Color> systemColorGetter ) {
|
||||
FlatLaf.systemColorGetter = systemColorGetter;
|
||||
}
|
||||
|
||||
private static void reSetLookAndFeel() {
|
||||
EventQueue.invokeLater( () -> {
|
||||
LookAndFeel lookAndFeel = UIManager.getLookAndFeel();
|
||||
|
||||
@@ -84,6 +84,7 @@ class UIDefaultsLoader
|
||||
|
||||
private static int parseColorDepth;
|
||||
|
||||
private static Map<String, ColorUIResource> systemColorCache;
|
||||
private static final SoftCache<String, Object> fontCache = new SoftCache<>();
|
||||
|
||||
static void loadDefaultsFromProperties( Class<?> lookAndFeelClass, List<FlatDefaultsAddon> addons,
|
||||
@@ -105,6 +106,10 @@ class UIDefaultsLoader
|
||||
Properties additionalDefaults, boolean dark, UIDefaults defaults )
|
||||
{
|
||||
try {
|
||||
// temporary cache system colors while loading defaults,
|
||||
// which avoids that system color getter is invoked multiple times
|
||||
systemColorCache = (FlatLaf.getSystemColorGetter() != null) ? new HashMap<>() : null;
|
||||
|
||||
// load core properties files
|
||||
Properties properties = new Properties();
|
||||
for( Class<?> lafClass : lafClasses ) {
|
||||
@@ -276,6 +281,9 @@ class UIDefaultsLoader
|
||||
|
||||
// remember variables in defaults to allow using them in styles
|
||||
defaults.put( KEY_VARIABLES, variables );
|
||||
|
||||
// clear/disable system color cache
|
||||
systemColorCache = null;
|
||||
} catch( IOException ex ) {
|
||||
LoggingFacade.INSTANCE.logSevere( "FlatLaf: Failed to load properties files.", ex );
|
||||
}
|
||||
@@ -769,6 +777,7 @@ class UIDefaultsLoader
|
||||
try {
|
||||
switch( function ) {
|
||||
case "if": return parseColorIf( value, params, resolver );
|
||||
case "systemColor": return parseColorSystemColor( value, params, resolver );
|
||||
case "rgb": return parseColorRgbOrRgba( false, params, resolver );
|
||||
case "rgba": return parseColorRgbOrRgba( true, params, resolver );
|
||||
case "hsl": return parseColorHslOrHsla( false, params );
|
||||
@@ -813,6 +822,44 @@ class UIDefaultsLoader
|
||||
return parseColorOrFunction( resolver.apply( ifValue ), resolver );
|
||||
}
|
||||
|
||||
/**
|
||||
* Syntax: systemColor(name[,defaultValue])
|
||||
* - name: system color name
|
||||
* - defaultValue: default color value used if system color is not available
|
||||
*/
|
||||
private static Object parseColorSystemColor( String value, List<String> params, Function<String, String> resolver ) {
|
||||
if( params.size() < 1 )
|
||||
throwMissingParametersException( value );
|
||||
|
||||
ColorUIResource systemColor = getSystemColor( params.get( 0 ) );
|
||||
if( systemColor != null )
|
||||
return systemColor;
|
||||
|
||||
String defaultValue = (params.size() > 1) ? params.get( 1 ) : "";
|
||||
if( defaultValue.equals( "null" ) || defaultValue.isEmpty() )
|
||||
return null;
|
||||
|
||||
return parseColorOrFunction( resolver.apply( defaultValue ), resolver );
|
||||
}
|
||||
|
||||
private static ColorUIResource getSystemColor( String name ) {
|
||||
Function<String, Color> systemColorGetter = FlatLaf.getSystemColorGetter();
|
||||
if( systemColorGetter == null )
|
||||
return null;
|
||||
|
||||
// use containsKey() because value may be null
|
||||
if( systemColorCache != null && systemColorCache.containsKey( name ) )
|
||||
return systemColorCache.get( name );
|
||||
|
||||
Color color = systemColorGetter.apply( name );
|
||||
ColorUIResource uiColor = (color != null) ? new ColorUIResource( color ) : null;
|
||||
|
||||
if( systemColorCache != null )
|
||||
systemColorCache.put( name, uiColor );
|
||||
|
||||
return uiColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Syntax: rgb(red,green,blue) or rgba(red,green,blue,alpha)
|
||||
* - red: an integer 0-255 or a percentage 0-100%
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
# accent colors (blueish)
|
||||
# set @accentColor to use single accent color or
|
||||
# modify @accentBaseColor to use variations of accent base color
|
||||
@accentColor = null
|
||||
@accentColor = systemColor(accent,null)
|
||||
@accentBaseColor = #4B6EAF
|
||||
@accentBase2Color = lighten(saturate(spin(@accentBaseColor,-8),13%),5%)
|
||||
# accent color variations
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
# accent colors (blueish)
|
||||
# set @accentColor to use single accent color or
|
||||
# modify @accentBaseColor to use variations of accent base color
|
||||
@accentColor = null
|
||||
@accentColor = systemColor(accent,null)
|
||||
@accentBaseColor = #2675BF
|
||||
@accentBase2Color = lighten(saturate(@accentBaseColor,10%),6%)
|
||||
# accent color variations
|
||||
|
||||
@@ -24,7 +24,6 @@ import java.net.URISyntaxException;
|
||||
import java.time.Year;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.prefs.Preferences;
|
||||
import javax.swing.*;
|
||||
import javax.swing.text.DefaultEditorKit;
|
||||
@@ -398,6 +397,7 @@ class DemoFrame
|
||||
};
|
||||
private final JToggleButton[] accentColorButtons = new JToggleButton[accentColorKeys.length];
|
||||
private JLabel accentColorLabel;
|
||||
private Color accentColor;
|
||||
|
||||
private void initAccentColors() {
|
||||
accentColorLabel = new JLabel( "Accent color: " );
|
||||
@@ -416,6 +416,10 @@ class DemoFrame
|
||||
|
||||
accentColorButtons[0].setSelected( true );
|
||||
|
||||
FlatLaf.setSystemColorGetter( name -> {
|
||||
return name.equals( "accent" ) ? accentColor : null;
|
||||
} );
|
||||
|
||||
UIManager.addPropertyChangeListener( e -> {
|
||||
if( "lookAndFeel".equals( e.getPropertyName() ) )
|
||||
updateAccentColorButtons();
|
||||
@@ -424,17 +428,17 @@ class DemoFrame
|
||||
}
|
||||
|
||||
private void accentColorChanged( ActionEvent e ) {
|
||||
String accentColor = accentColorKeys[0];
|
||||
String accentColorKey = null;
|
||||
for( int i = 0; i < accentColorButtons.length; i++ ) {
|
||||
if( accentColorButtons[i].isSelected() ) {
|
||||
accentColor = accentColorKeys[i];
|
||||
accentColorKey = accentColorKeys[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
FlatLaf.setGlobalExtraDefaults( (accentColor != accentColorKeys[0])
|
||||
? Collections.singletonMap( "@accentColor", "$" + accentColor )
|
||||
: null );
|
||||
accentColor = (accentColorKey != null && accentColorKey != accentColorKeys[0])
|
||||
? UIManager.getColor( accentColorKey )
|
||||
: null;
|
||||
|
||||
Class<? extends LookAndFeel> lafClass = UIManager.getLookAndFeel().getClass();
|
||||
try {
|
||||
|
||||
@@ -410,6 +410,10 @@ class FlatCompletionProvider
|
||||
addFunction( "lazy",
|
||||
"uiKey", "UI key (without leading '$')" );
|
||||
|
||||
addFunction( "systemColor",
|
||||
"name", "system color name",
|
||||
"defaultValue", "default color value used if system color is not available" );
|
||||
|
||||
addFunction( "rgb",
|
||||
"red", "0-255 or 0-100%",
|
||||
"green", "0-255 or 0-100%",
|
||||
|
||||
@@ -56,6 +56,7 @@ public class FlatThemeTokenMaker
|
||||
tokenMap.put( "lazy", TOKEN_FUNCTION );
|
||||
|
||||
// color functions
|
||||
tokenMap.put( "systemColor", TOKEN_FUNCTION );
|
||||
tokenMap.put( "rgb", TOKEN_FUNCTION );
|
||||
tokenMap.put( "rgba", TOKEN_FUNCTION );
|
||||
tokenMap.put( "hsl", TOKEN_FUNCTION );
|
||||
|
||||
@@ -49,6 +49,9 @@ Prop.ifColor = lighten(if(#000,#0f0,#dfd), 10%)
|
||||
Prop.ifColorVar = lighten(if(@varTrue,@varTrueValue,@varFalseValue), 10%)
|
||||
Prop.lazy = lazy(Prop.string)
|
||||
|
||||
Prop.systemColor1 = systemColor(accent,null)
|
||||
Prop.systemColor2 = systemColor(accent,#f00)
|
||||
|
||||
Prop.colorFunc1 = rgb(12,34,56)
|
||||
Prop.colorFunc2 = rgba(12,34,56,78)
|
||||
Prop.colorFunc3 = hsl(12,34%,56%)
|
||||
|
||||
Reference in New Issue
Block a user