diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/UIDefaultsLoader.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/UIDefaultsLoader.java index aaa9e618..aab35cb2 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/UIDefaultsLoader.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/UIDefaultsLoader.java @@ -26,6 +26,9 @@ import java.io.IOException; import java.io.InputStream; import java.io.StreamTokenizer; import java.io.StringReader; +import java.lang.ref.Reference; +import java.lang.ref.ReferenceQueue; +import java.lang.ref.SoftReference; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -79,6 +82,8 @@ class UIDefaultsLoader private static int parseColorDepth; + private static final Cache fontCache = new Cache<>(); + static void loadDefaultsFromProperties( Class lookAndFeelClass, List addons, Properties additionalDefaults, boolean dark, UIDefaults defaults ) { @@ -995,6 +1000,10 @@ class UIDefaultsLoader * Syntax: [normal] [bold|+bold|-bold] [italic|+italic|-italic] [|+|-|%] [family[, family]] */ private static Object parseFont( String value ) { + Object font = fontCache.get( value ); + if( font != null ) + return font; + int style = -1; int styleChange = 0; int absoluteSize = 0; @@ -1076,7 +1085,9 @@ class UIDefaultsLoader throw new IllegalArgumentException( "can not use '+italic' and '-italic' in '" + value + "'" ); } - return new FlatLaf.ActiveFont( families, style, styleChange, absoluteSize, relativeSize, scaleSize ); + font = new FlatLaf.ActiveFont( families, style, styleChange, absoluteSize, relativeSize, scaleSize ); + fontCache.put( value, font ); + return font; } private static int parsePercentage( String value ) { @@ -1229,4 +1240,43 @@ class UIDefaultsLoader private static void throwMissingParametersException( String value ) { throw new IllegalArgumentException( "missing parameters in function '" + value + "'" ); } + + //---- class Cache -------------------------------------------------------- + + private static class Cache + { + private final Map> map = new HashMap<>(); + private final ReferenceQueue queue = new ReferenceQueue<>(); + + V get( K key ) { + expungeStaleEntries(); + CacheReference ref = map.get( key ); + return (ref != null) ? ref.get() : null; + } + + void put( K key, V value ) { + expungeStaleEntries(); + map.put( key, new CacheReference<>( key, value, queue ) ); + } + + @SuppressWarnings( "unchecked" ) + void expungeStaleEntries() { + Reference reference; + while( (reference = queue.poll()) != null ) + map.remove( ((CacheReference)reference).key ); + } + + //---- class CacheReference ---- + + private static class CacheReference + extends SoftReference + { + final K key; + + public CacheReference( K key, V value, ReferenceQueue queue ) { + super( value, queue ); + this.key = key; + } + } + } }