use AtomicReference for method parameters that return values

This commit is contained in:
Karl Tauber
2025-11-29 14:31:05 +01:00
parent d3e6c7af14
commit e61499e7c6
6 changed files with 36 additions and 31 deletions

View File

@@ -45,6 +45,7 @@ import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Properties; import java.util.Properties;
import java.util.Set; import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Function; import java.util.function.Function;
import javax.swing.Icon; import javax.swing.Icon;
@@ -431,7 +432,7 @@ class UIDefaultsLoader
enum ValueType { UNKNOWN, STRING, BOOLEAN, CHARACTER, INTEGER, INTEGERORFLOAT, FLOAT, BORDER, ICON, INSETS, DIMENSION, COLOR, FONT, enum ValueType { UNKNOWN, STRING, BOOLEAN, CHARACTER, INTEGER, INTEGERORFLOAT, FLOAT, BORDER, ICON, INSETS, DIMENSION, COLOR, FONT,
SCALEDINTEGER, SCALEDFLOAT, SCALEDINSETS, SCALEDDIMENSION, INSTANCE, CLASS, GRAYFILTER, NULL, LAZY } SCALEDINTEGER, SCALEDFLOAT, SCALEDINSETS, SCALEDDIMENSION, INSTANCE, CLASS, GRAYFILTER, NULL, LAZY }
private static final ValueType[] tempResultValueType = new ValueType[1]; private static final AtomicReference<ValueType> tempResultValueType = new AtomicReference<>();
private static Map<Class<?>, ValueType> javaValueTypes; private static Map<Class<?>, ValueType> javaValueTypes;
private static Map<String, ValueType> knownValueTypes; private static Map<String, ValueType> knownValueTypes;
@@ -441,7 +442,7 @@ class UIDefaultsLoader
return parseValue( key, value, valueType, null, v -> v, Collections.emptyList() ); return parseValue( key, value, valueType, null, v -> v, Collections.emptyList() );
} }
static Object parseValue( String key, String value, Class<?> javaValueType, ValueType[] resultValueType, static Object parseValue( String key, String value, Class<?> javaValueType, AtomicReference<ValueType> resultValueType,
Function<String, String> resolver, List<ClassLoader> addonClassLoaders ) Function<String, String> resolver, List<ClassLoader> addonClassLoaders )
throws IllegalArgumentException throws IllegalArgumentException
{ {
@@ -450,7 +451,7 @@ class UIDefaultsLoader
// do not parse styles here // do not parse styles here
if( key.startsWith( "[style]" ) ) { if( key.startsWith( "[style]" ) ) {
resultValueType[0] = ValueType.STRING; resultValueType.set( ValueType.STRING );
return value; return value;
} }
@@ -458,7 +459,7 @@ class UIDefaultsLoader
// null // null
if( value.equals( "null" ) || value.isEmpty() ) { if( value.equals( "null" ) || value.isEmpty() ) {
resultValueType[0] = ValueType.NULL; resultValueType.set( ValueType.NULL );
return null; return null;
} }
@@ -514,14 +515,14 @@ class UIDefaultsLoader
} else { } else {
// false, true // false, true
switch( value ) { switch( value ) {
case "false": resultValueType[0] = ValueType.BOOLEAN; return false; case "false": resultValueType.set( ValueType.BOOLEAN ); return false;
case "true": resultValueType[0] = ValueType.BOOLEAN; return true; case "true": resultValueType.set( ValueType.BOOLEAN ); return true;
} }
// check for function "lazy" // check for function "lazy"
// Syntax: lazy(uiKey) // Syntax: lazy(uiKey)
if( value.startsWith( "lazy(" ) && value.endsWith( ")" ) ) { if( value.startsWith( "lazy(" ) && value.endsWith( ")" ) ) {
resultValueType[0] = ValueType.LAZY; resultValueType.set( ValueType.LAZY );
String uiKey = StringUtils.substringTrimmed( value, 5, value.length() - 1 ); String uiKey = StringUtils.substringTrimmed( value, 5, value.length() - 1 );
return (LazyValue) t -> { return (LazyValue) t -> {
return lazyUIManagerGet( uiKey ); return lazyUIManagerGet( uiKey );
@@ -602,7 +603,7 @@ class UIDefaultsLoader
} }
} }
resultValueType[0] = valueType; resultValueType.set( valueType );
// parse value // parse value
switch( valueType ) { switch( valueType ) {
@@ -629,14 +630,14 @@ class UIDefaultsLoader
default: default:
// string // string
if( value.startsWith( "\"" ) && value.endsWith( "\"" ) ) { if( value.startsWith( "\"" ) && value.endsWith( "\"" ) ) {
resultValueType[0] = ValueType.STRING; resultValueType.set( ValueType.STRING );
return value.substring( 1, value.length() - 1 ); return value.substring( 1, value.length() - 1 );
} }
// colors // colors
if( value.startsWith( "#" ) || value.endsWith( ")" ) ) { if( value.startsWith( "#" ) || value.endsWith( ")" ) ) {
Object color = parseColorOrFunction( value, resolver ); Object color = parseColorOrFunction( value, resolver );
resultValueType[0] = (color != null) ? ValueType.COLOR : ValueType.NULL; resultValueType.set( (color != null) ? ValueType.COLOR : ValueType.NULL );
return color; return color;
} }
@@ -648,7 +649,7 @@ class UIDefaultsLoader
// integer // integer
try { try {
Integer integer = parseInteger( value ); Integer integer = parseInteger( value );
resultValueType[0] = ValueType.INTEGER; resultValueType.set( ValueType.INTEGER );
return integer; return integer;
} catch( NumberFormatException ex ) { } catch( NumberFormatException ex ) {
// ignore // ignore
@@ -657,7 +658,7 @@ class UIDefaultsLoader
// float // float
try { try {
Float f = parseFloat( value ); Float f = parseFloat( value );
resultValueType[0] = ValueType.FLOAT; resultValueType.set( ValueType.FLOAT );
return f; return f;
} catch( NumberFormatException ex ) { } catch( NumberFormatException ex ) {
// ignore // ignore
@@ -665,7 +666,7 @@ class UIDefaultsLoader
} }
// string // string
resultValueType[0] = ValueType.STRING; resultValueType.set( ValueType.STRING );
return value; return value;
} }
} }

View File

@@ -30,6 +30,7 @@ import java.util.HashSet;
import java.util.Locale; import java.util.Locale;
import java.util.Properties; import java.util.Properties;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.concurrent.atomic.AtomicReference;
import java.util.Set; import java.util.Set;
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.prefs.Preferences; import java.util.prefs.Preferences;
@@ -310,7 +311,7 @@ public class FlatUIDefaultsInspector
Set<Entry<Object, Object>> defaultsSet = defaults.entrySet(); Set<Entry<Object, Object>> defaultsSet = defaults.entrySet();
ArrayList<Item> items = new ArrayList<>( defaultsSet.size() ); ArrayList<Item> items = new ArrayList<>( defaultsSet.size() );
HashSet<Object> keys = new HashSet<>( defaultsSet.size() ); HashSet<Object> keys = new HashSet<>( defaultsSet.size() );
Color[] pBaseColor = new Color[1]; AtomicReference<Color> pBaseColor = new AtomicReference<>();
for( Entry<Object,Object> e : defaultsSet ) { for( Entry<Object,Object> e : defaultsSet ) {
Object key = e.getKey(); Object key = e.getKey();
@@ -336,7 +337,7 @@ public class FlatUIDefaultsInspector
if( value instanceof DerivedColor ) { if( value instanceof DerivedColor ) {
Color resolvedColor = resolveDerivedColor( defaults, (String) key, (DerivedColor) value, pBaseColor ); Color resolvedColor = resolveDerivedColor( defaults, (String) key, (DerivedColor) value, pBaseColor );
if( resolvedColor != value ) if( resolvedColor != value )
info = new Color[] { resolvedColor, pBaseColor[0] }; info = new Color[] { resolvedColor, pBaseColor.get() };
} }
// check whether key was overridden using UIManager.put(key,value) // check whether key was overridden using UIManager.put(key,value)
@@ -351,9 +352,9 @@ public class FlatUIDefaultsInspector
return items.toArray( new Item[items.size()] ); return items.toArray( new Item[items.size()] );
} }
private Color resolveDerivedColor( UIDefaults defaults, String key, Color color, Color[] pBaseColor ) { private Color resolveDerivedColor( UIDefaults defaults, String key, Color color, AtomicReference<Color> pBaseColor ) {
if( pBaseColor != null ) if( pBaseColor != null )
pBaseColor[0] = null; pBaseColor.set( null );
if( !(color instanceof DerivedColor) ) if( !(color instanceof DerivedColor) )
return color; return color;
@@ -377,7 +378,7 @@ public class FlatUIDefaultsInspector
baseColor = resolveDerivedColor( defaults, (String) baseKey, baseColor, null ); baseColor = resolveDerivedColor( defaults, (String) baseKey, baseColor, null );
if( pBaseColor != null ) if( pBaseColor != null )
pBaseColor[0] = baseColor; pBaseColor.set( baseColor );
Color newColor = FlatUIUtils.deriveColor( color, baseColor ); Color newColor = FlatUIUtils.deriveColor( color, baseColor );

View File

@@ -23,6 +23,7 @@ import java.awt.event.ComponentListener;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import java.awt.event.WindowEvent; import java.awt.event.WindowEvent;
import java.awt.event.WindowListener; import java.awt.event.WindowListener;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer; import java.util.function.Consumer;
import javax.swing.JButton; import javax.swing.JButton;
import javax.swing.JComponent; import javax.swing.JComponent;
@@ -143,7 +144,7 @@ public class FlatWindowMaximizeTest
} }
private static void testMaximize( String msg, int expectedState, boolean showLater, Consumer<JFrame> testFunc ) { private static void testMaximize( String msg, int expectedState, boolean showLater, Consumer<JFrame> testFunc ) {
JFrame[] pFrame = new JFrame[1]; AtomicReference<JFrame> pFrame = new AtomicReference<>();
EventQueue.invokeLater( () -> { EventQueue.invokeLater( () -> {
JFrame frame = new JFrame( "test" ); JFrame frame = new JFrame( "test" );
frame.setName( msg ); frame.setName( msg );
@@ -164,7 +165,7 @@ public class FlatWindowMaximizeTest
testFunc.accept( frame ); testFunc.accept( frame );
if( !showLater ) if( !showLater )
frame.setVisible( true ); frame.setVisible( true );
pFrame[0] = frame; pFrame.set( frame );
} ); } );
try { try {
@@ -172,14 +173,14 @@ public class FlatWindowMaximizeTest
Thread.sleep( 500 ); Thread.sleep( 500 );
EventQueue.invokeLater( () -> { EventQueue.invokeLater( () -> {
pFrame[0].setVisible( true ); pFrame.get().setVisible( true );
} ); } );
} }
Thread.sleep( 500 ); Thread.sleep( 500 );
EventQueue.invokeAndWait( () -> { EventQueue.invokeAndWait( () -> {
int state = pFrame[0].getExtendedState(); int state = pFrame.get().getExtendedState();
System.out.printf( " %-15s: %d %s\n", msg, state, (state != expectedState ? " FAILED" : "") ); System.out.printf( " %-15s: %d %s\n", msg, state, (state != expectedState ? " FAILED" : "") );
} ); } );
} catch( Exception ex ) { } catch( Exception ex ) {

View File

@@ -645,14 +645,14 @@ public class UIDefaultsDump
} }
private void dumpColor( PrintWriter out, String key, Color color ) { private void dumpColor( PrintWriter out, String key, Color color ) {
Color[] retBaseColor = new Color[1]; AtomicReference<Color> retBaseColor = new AtomicReference<>();
Color resolvedColor = resolveDerivedColor( key, color, retBaseColor ); Color resolvedColor = resolveDerivedColor( key, color, retBaseColor );
if( resolvedColor != color && resolvedColor.getRGB() != color.getRGB() ) { if( resolvedColor != color && resolvedColor.getRGB() != color.getRGB() ) {
if( !isIntelliJTheme ) { if( !isIntelliJTheme ) {
System.err.println( "Key '" + key + "': derived colors not equal" ); System.err.println( "Key '" + key + "': derived colors not equal" );
System.err.println( " Default color: " + dumpColorHexAndHSL( color ) ); System.err.println( " Default color: " + dumpColorHexAndHSL( color ) );
System.err.println( " Resolved color: " + dumpColorHexAndHSL( resolvedColor ) ); System.err.println( " Resolved color: " + dumpColorHexAndHSL( resolvedColor ) );
System.err.println( " Base color: " + dumpColorHexAndHSL( retBaseColor[0] ) ); System.err.println( " Base color: " + dumpColorHexAndHSL( retBaseColor.get() ) );
} }
out.printf( "%s / ", out.printf( "%s / ",
@@ -891,7 +891,7 @@ public class UIDefaultsDump
return properties; return properties;
} }
private Color resolveDerivedColor( String key, Color color, Color[] retBaseColor ) { private Color resolveDerivedColor( String key, Color color, AtomicReference<Color> retBaseColor ) {
if( !(color instanceof DerivedColor) ) if( !(color instanceof DerivedColor) )
return color; return color;
@@ -914,7 +914,7 @@ public class UIDefaultsDump
if( baseColor instanceof DerivedColor ) if( baseColor instanceof DerivedColor )
baseColor = resolveDerivedColor( (String) baseKey, baseColor, retBaseColor ); baseColor = resolveDerivedColor( (String) baseKey, baseColor, retBaseColor );
retBaseColor[0] = baseColor; retBaseColor.set( baseColor );
Color newColor = FlatUIUtils.deriveColor( color, baseColor ); Color newColor = FlatUIUtils.deriveColor( color, baseColor );

View File

@@ -18,6 +18,7 @@ package com.formdev.flatlaf;
import java.util.Collections; import java.util.Collections;
import java.util.Properties; import java.util.Properties;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function; import java.util.function.Function;
import com.formdev.flatlaf.UIDefaultsLoader.ValueType; import com.formdev.flatlaf.UIDefaultsLoader.ValueType;
@@ -57,14 +58,14 @@ public class UIDefaultsLoaderAccessor
return UIDefaultsLoader.resolveValue( value, propertiesGetter ); return UIDefaultsLoader.resolveValue( value, propertiesGetter );
} }
public static Object parseValue( String key, String value, Object[] resultValueType, public static Object parseValue( String key, String value, AtomicReference<Object> resultValueType,
Function<String, String> resolver ) Function<String, String> resolver )
throws IllegalArgumentException throws IllegalArgumentException
{ {
ValueType[] resultValueType2 = new ValueType[1]; AtomicReference<ValueType> resultValueType2 = new AtomicReference<>();
Object result = UIDefaultsLoader.parseValue( key, value, null, Object result = UIDefaultsLoader.parseValue( key, value, null,
resultValueType2, resolver, Collections.emptyList() ); resultValueType2, resolver, Collections.emptyList() );
resultValueType[0] = resultValueType2[0]; resultValueType.set( resultValueType2.get() );
return result; return result;
} }

View File

@@ -26,6 +26,7 @@ import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.Set; import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function; import java.util.function.Function;
import javax.swing.UIDefaults; import javax.swing.UIDefaults;
import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentEvent;
@@ -96,7 +97,7 @@ class FlatThemePropertiesSupport
return null; return null;
try { try {
Object[] resultValueType = new Object[1]; AtomicReference<Object> resultValueType = new AtomicReference<>();
String value = resolveValue( keyValue.value ); String value = resolveValue( keyValue.value );
parsedValue = UIDefaultsLoaderAccessor.parseValue( keyValue.key, value, resultValueType, resolver ); parsedValue = UIDefaultsLoaderAccessor.parseValue( keyValue.key, value, resultValueType, resolver );
parsedValueCache.put( lineKey, parsedValue ); parsedValueCache.put( lineKey, parsedValue );
@@ -156,7 +157,7 @@ class FlatThemePropertiesSupport
return null; return null;
try { try {
Object[] resultValueType = new Object[1]; AtomicReference<Object> resultValueType = new AtomicReference<>();
String value = resolveValue( str ); String value = resolveValue( str );
parsedValue = UIDefaultsLoaderAccessor.parseValue( key, value, resultValueType, resolver ); parsedValue = UIDefaultsLoaderAccessor.parseValue( key, value, resultValueType, resolver );
parsedValueCache2.put( key, parsedValue ); parsedValueCache2.put( key, parsedValue );