mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2026-02-10 22:17:13 -06:00
Styling: support specifying explicit value type for parsing CSS values (for future use)
This commit is contained in:
@@ -784,14 +784,17 @@ public abstract class FlatLaf
|
|||||||
* <p>
|
* <p>
|
||||||
* See: <a href="https://www.formdev.com/flatlaf/properties-files/">https://www.formdev.com/flatlaf/properties-files/</a>
|
* See: <a href="https://www.formdev.com/flatlaf/properties-files/">https://www.formdev.com/flatlaf/properties-files/</a>
|
||||||
*
|
*
|
||||||
* @param key the key, which is used to determine the value type
|
* @param key the key, which is used to determine the value type if parameter {@code valueType} is {@code null}
|
||||||
* @param value the value string
|
* @param value the value string
|
||||||
|
* @param valueType the expected value type, or {@code null}
|
||||||
* @return the binary value
|
* @return the binary value
|
||||||
* @throws IllegalArgumentException on syntax errors
|
* @throws IllegalArgumentException on syntax errors
|
||||||
* @since TODO
|
* @since TODO
|
||||||
*/
|
*/
|
||||||
public static Object parseDefaultsValue( String key, String value ) throws IllegalArgumentException {
|
public static Object parseDefaultsValue( String key, String value, Class<?> valueType )
|
||||||
return UIDefaultsLoader.parseValue( key, value );
|
throws IllegalArgumentException
|
||||||
|
{
|
||||||
|
return UIDefaultsLoader.parseValue( key, value, valueType );
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void reSetLookAndFeel() {
|
private static void reSetLookAndFeel() {
|
||||||
|
|||||||
@@ -338,7 +338,7 @@ public class IntelliJTheme
|
|||||||
|
|
||||||
// parse value
|
// parse value
|
||||||
try {
|
try {
|
||||||
uiValue = UIDefaultsLoader.parseValue( key, valueStr );
|
uiValue = UIDefaultsLoader.parseValue( key, valueStr, null );
|
||||||
} catch( RuntimeException ex ) {
|
} catch( RuntimeException ex ) {
|
||||||
UIDefaultsLoader.logParseError( key, valueStr, ex, false );
|
UIDefaultsLoader.logParseError( key, valueStr, ex, false );
|
||||||
return; // ignore invalid value
|
return; // ignore invalid value
|
||||||
|
|||||||
@@ -33,8 +33,10 @@ 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.function.Function;
|
import java.util.function.Function;
|
||||||
|
import javax.swing.Icon;
|
||||||
import javax.swing.UIDefaults;
|
import javax.swing.UIDefaults;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
|
import javax.swing.border.Border;
|
||||||
import javax.swing.UIDefaults.ActiveValue;
|
import javax.swing.UIDefaults.ActiveValue;
|
||||||
import javax.swing.UIDefaults.LazyValue;
|
import javax.swing.UIDefaults.LazyValue;
|
||||||
import javax.swing.plaf.ColorUIResource;
|
import javax.swing.plaf.ColorUIResource;
|
||||||
@@ -241,7 +243,7 @@ class UIDefaultsLoader
|
|||||||
|
|
||||||
String value = resolveValue( (String) e.getValue(), propertiesGetter );
|
String value = resolveValue( (String) e.getValue(), propertiesGetter );
|
||||||
try {
|
try {
|
||||||
defaults.put( key, parseValue( key, value, null, resolver, addonClassLoaders ) );
|
defaults.put( key, parseValue( key, value, null, null, resolver, addonClassLoaders ) );
|
||||||
} catch( RuntimeException ex ) {
|
} catch( RuntimeException ex ) {
|
||||||
logParseError( key, value, ex, true );
|
logParseError( key, value, ex, true );
|
||||||
}
|
}
|
||||||
@@ -292,12 +294,13 @@ class UIDefaultsLoader
|
|||||||
SCALEDINTEGER, SCALEDFLOAT, SCALEDINSETS, SCALEDDIMENSION, INSTANCE, CLASS, GRAYFILTER, NULL, LAZY }
|
SCALEDINTEGER, SCALEDFLOAT, SCALEDINSETS, SCALEDDIMENSION, INSTANCE, CLASS, GRAYFILTER, NULL, LAZY }
|
||||||
|
|
||||||
private static ValueType[] tempResultValueType = new ValueType[1];
|
private static ValueType[] tempResultValueType = new ValueType[1];
|
||||||
|
private static Map<Class<?>, ValueType> javaValueTypes;
|
||||||
|
|
||||||
static Object parseValue( String key, String value ) {
|
static Object parseValue( String key, String value, Class<?> valueType ) {
|
||||||
return parseValue( key, value, null, v -> v, Collections.emptyList() );
|
return parseValue( key, value, valueType, null, v -> v, Collections.emptyList() );
|
||||||
}
|
}
|
||||||
|
|
||||||
static Object parseValue( String key, String value, ValueType[] resultValueType,
|
static Object parseValue( String key, String value, Class<?> javaValueType, ValueType[] resultValueType,
|
||||||
Function<String, String> resolver, List<ClassLoader> addonClassLoaders )
|
Function<String, String> resolver, List<ClassLoader> addonClassLoaders )
|
||||||
{
|
{
|
||||||
if( resultValueType == null )
|
if( resultValueType == null )
|
||||||
@@ -305,71 +308,106 @@ class UIDefaultsLoader
|
|||||||
|
|
||||||
value = value.trim();
|
value = value.trim();
|
||||||
|
|
||||||
// null, false, true
|
// null
|
||||||
switch( value ) {
|
if( value.equals( "null" ) ) {
|
||||||
case "null": resultValueType[0] = ValueType.NULL; return null;
|
resultValueType[0] = ValueType.NULL;
|
||||||
case "false": resultValueType[0] = ValueType.BOOLEAN; return false;
|
return null;
|
||||||
case "true": resultValueType[0] = ValueType.BOOLEAN; return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check for function "lazy"
|
|
||||||
// Syntax: lazy(uiKey)
|
|
||||||
if( value.startsWith( "lazy(" ) && value.endsWith( ")" ) ) {
|
|
||||||
resultValueType[0] = ValueType.LAZY;
|
|
||||||
String uiKey = value.substring( 5, value.length() - 1 ).trim();
|
|
||||||
return (LazyValue) t -> {
|
|
||||||
return lazyUIManagerGet( uiKey );
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueType valueType = ValueType.UNKNOWN;
|
ValueType valueType = ValueType.UNKNOWN;
|
||||||
|
|
||||||
// check whether value type is specified in the value
|
if( javaValueType != null ) {
|
||||||
if( value.startsWith( "#" ) )
|
if( javaValueTypes == null ) {
|
||||||
valueType = ValueType.COLOR;
|
// create lazy
|
||||||
else if( value.startsWith( "\"" ) && value.endsWith( "\"" ) ) {
|
javaValueTypes = new HashMap<>();
|
||||||
valueType = ValueType.STRING;
|
javaValueTypes.put( String.class, ValueType.STRING );
|
||||||
value = value.substring( 1, value.length() - 1 );
|
javaValueTypes.put( boolean.class, ValueType.BOOLEAN );
|
||||||
} else if( value.startsWith( TYPE_PREFIX ) ) {
|
javaValueTypes.put( Boolean.class, ValueType.BOOLEAN );
|
||||||
int end = value.indexOf( TYPE_PREFIX_END );
|
javaValueTypes.put( char.class, ValueType.CHARACTER );
|
||||||
if( end != -1 ) {
|
javaValueTypes.put( Character.class, ValueType.CHARACTER );
|
||||||
try {
|
javaValueTypes.put( int.class, ValueType.INTEGER );
|
||||||
String typeStr = value.substring( TYPE_PREFIX.length(), end );
|
javaValueTypes.put( Integer.class, ValueType.INTEGER );
|
||||||
valueType = ValueType.valueOf( typeStr.toUpperCase( Locale.ENGLISH ) );
|
javaValueTypes.put( float.class, ValueType.FLOAT );
|
||||||
|
javaValueTypes.put( Float.class, ValueType.FLOAT );
|
||||||
|
javaValueTypes.put( Border.class, ValueType.BORDER );
|
||||||
|
javaValueTypes.put( Icon.class, ValueType.ICON );
|
||||||
|
javaValueTypes.put( Insets.class, ValueType.INSETS );
|
||||||
|
javaValueTypes.put( Dimension.class, ValueType.DIMENSION );
|
||||||
|
javaValueTypes.put( Color.class, ValueType.COLOR );
|
||||||
|
}
|
||||||
|
|
||||||
// remove type from value
|
// map java value type to parser value type
|
||||||
value = value.substring( end + TYPE_PREFIX_END.length() );
|
valueType = javaValueTypes.get( javaValueType );
|
||||||
} catch( IllegalArgumentException ex ) {
|
if( valueType == null )
|
||||||
// ignore
|
throw new IllegalArgumentException( "unsupported value type '" + javaValueType.getName() + "'" );
|
||||||
|
|
||||||
|
// remove '"' from strings
|
||||||
|
if( valueType == ValueType.STRING && value.startsWith( "\"" ) && value.endsWith( "\"" ) )
|
||||||
|
value = value.substring( 1, value.length() - 1 );
|
||||||
|
} else {
|
||||||
|
// false, true
|
||||||
|
switch( value ) {
|
||||||
|
case "false": resultValueType[0] = ValueType.BOOLEAN; return false;
|
||||||
|
case "true": resultValueType[0] = ValueType.BOOLEAN; return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for function "lazy"
|
||||||
|
// Syntax: lazy(uiKey)
|
||||||
|
if( value.startsWith( "lazy(" ) && value.endsWith( ")" ) ) {
|
||||||
|
resultValueType[0] = ValueType.LAZY;
|
||||||
|
String uiKey = value.substring( 5, value.length() - 1 ).trim();
|
||||||
|
return (LazyValue) t -> {
|
||||||
|
return lazyUIManagerGet( uiKey );
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// check whether value type is specified in the value
|
||||||
|
if( value.startsWith( "#" ) )
|
||||||
|
valueType = ValueType.COLOR;
|
||||||
|
else if( value.startsWith( "\"" ) && value.endsWith( "\"" ) ) {
|
||||||
|
valueType = ValueType.STRING;
|
||||||
|
value = value.substring( 1, value.length() - 1 );
|
||||||
|
} else if( value.startsWith( TYPE_PREFIX ) ) {
|
||||||
|
int end = value.indexOf( TYPE_PREFIX_END );
|
||||||
|
if( end != -1 ) {
|
||||||
|
try {
|
||||||
|
String typeStr = value.substring( TYPE_PREFIX.length(), end );
|
||||||
|
valueType = ValueType.valueOf( typeStr.toUpperCase( Locale.ENGLISH ) );
|
||||||
|
|
||||||
|
// remove type from value
|
||||||
|
value = value.substring( end + TYPE_PREFIX_END.length() );
|
||||||
|
} catch( IllegalArgumentException ex ) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// determine value type from key
|
// determine value type from key
|
||||||
if( valueType == ValueType.UNKNOWN ) {
|
if( valueType == ValueType.UNKNOWN ) {
|
||||||
if( key.endsWith( "UI" ) )
|
if( key.endsWith( "UI" ) )
|
||||||
valueType = ValueType.STRING;
|
valueType = ValueType.STRING;
|
||||||
else if( key.endsWith( "Color" ) ||
|
else if( key.endsWith( "Color" ) ||
|
||||||
(key.endsWith( "ground" ) &&
|
(key.endsWith( "ground" ) &&
|
||||||
(key.endsWith( ".background" ) || key.endsWith( "Background" ) || key.equals( "background" ) ||
|
(key.endsWith( ".background" ) || key.endsWith( "Background" ) || key.equals( "background" ) ||
|
||||||
key.endsWith( ".foreground" ) || key.endsWith( "Foreground" ) || key.equals( "foreground" ))) )
|
key.endsWith( ".foreground" ) || key.endsWith( "Foreground" ) || key.equals( "foreground" ))) )
|
||||||
valueType = ValueType.COLOR;
|
valueType = ValueType.COLOR;
|
||||||
else if( key.endsWith( ".border" ) || key.endsWith( "Border" ) )
|
else if( key.endsWith( ".border" ) || key.endsWith( "Border" ) )
|
||||||
valueType = ValueType.BORDER;
|
valueType = ValueType.BORDER;
|
||||||
else if( key.endsWith( ".icon" ) || key.endsWith( "Icon" ) )
|
else if( key.endsWith( ".icon" ) || key.endsWith( "Icon" ) )
|
||||||
valueType = ValueType.ICON;
|
valueType = ValueType.ICON;
|
||||||
else if( key.endsWith( ".margin" ) || key.equals( "margin" ) ||
|
else if( key.endsWith( ".margin" ) || key.equals( "margin" ) ||
|
||||||
key.endsWith( ".padding" ) || key.equals( "padding" ) ||
|
key.endsWith( ".padding" ) || key.equals( "padding" ) ||
|
||||||
key.endsWith( "Margins" ) || key.endsWith( "Insets" ) )
|
key.endsWith( "Margins" ) || key.endsWith( "Insets" ) )
|
||||||
valueType = ValueType.INSETS;
|
valueType = ValueType.INSETS;
|
||||||
else if( key.endsWith( "Size" ) )
|
else if( key.endsWith( "Size" ) )
|
||||||
valueType = ValueType.DIMENSION;
|
valueType = ValueType.DIMENSION;
|
||||||
else if( key.endsWith( "Width" ) || key.endsWith( "Height" ) )
|
else if( key.endsWith( "Width" ) || key.endsWith( "Height" ) )
|
||||||
valueType = ValueType.INTEGER;
|
valueType = ValueType.INTEGER;
|
||||||
else if( key.endsWith( "Char" ) )
|
else if( key.endsWith( "Char" ) )
|
||||||
valueType = ValueType.CHARACTER;
|
valueType = ValueType.CHARACTER;
|
||||||
else if( key.endsWith( "grayFilter" ) )
|
else if( key.endsWith( "grayFilter" ) )
|
||||||
valueType = ValueType.GRAYFILTER;
|
valueType = ValueType.GRAYFILTER;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resultValueType[0] = valueType;
|
resultValueType[0] = valueType;
|
||||||
@@ -377,6 +415,7 @@ class UIDefaultsLoader
|
|||||||
// parse value
|
// parse value
|
||||||
switch( valueType ) {
|
switch( valueType ) {
|
||||||
case STRING: return value;
|
case STRING: return value;
|
||||||
|
case BOOLEAN: return parseBoolean( value );
|
||||||
case CHARACTER: return parseCharacter( value );
|
case CHARACTER: return parseCharacter( value );
|
||||||
case INTEGER: return parseInteger( value, true );
|
case INTEGER: return parseInteger( value, true );
|
||||||
case FLOAT: return parseFloat( value, true );
|
case FLOAT: return parseFloat( value, true );
|
||||||
@@ -869,6 +908,14 @@ class UIDefaultsLoader
|
|||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Boolean parseBoolean( String value ) {
|
||||||
|
switch( value ) {
|
||||||
|
case "false": return false;
|
||||||
|
case "true": return true;
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException( "invalid boolean '" + value + "'" );
|
||||||
|
}
|
||||||
|
|
||||||
private static Character parseCharacter( String value ) {
|
private static Character parseCharacter( String value ) {
|
||||||
if( value.length() != 1 )
|
if( value.length() != 1 )
|
||||||
throw new IllegalArgumentException( "invalid character '" + value + "'" );
|
throw new IllegalArgumentException( "invalid character '" + value + "'" );
|
||||||
|
|||||||
@@ -198,7 +198,7 @@ public class FlatStyleSupport
|
|||||||
if( key.startsWith( "[" ) )
|
if( key.startsWith( "[" ) )
|
||||||
key = key.substring( key.indexOf( ']' ) + 1 );
|
key = key.substring( key.indexOf( ']' ) + 1 );
|
||||||
|
|
||||||
return FlatLaf.parseDefaultsValue( key, value );
|
return FlatLaf.parseDefaultsValue( key, value, null );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2021 FormDev Software GmbH
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.formdev.flatlaf;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Insets;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Karl Tauber
|
||||||
|
*/
|
||||||
|
public class TestUIDefaultsLoader
|
||||||
|
{
|
||||||
|
@Test
|
||||||
|
void parseValue() {
|
||||||
|
assertEquals( null, UIDefaultsLoader.parseValue( "dummy", "null", null ) );
|
||||||
|
assertEquals( false, UIDefaultsLoader.parseValue( "dummy", "false", null ) );
|
||||||
|
assertEquals( true, UIDefaultsLoader.parseValue( "dummy", "true", null ) );
|
||||||
|
|
||||||
|
assertEquals( "hello", UIDefaultsLoader.parseValue( "dummy", "hello", null ) );
|
||||||
|
assertEquals( "hello", UIDefaultsLoader.parseValue( "dummy", "\"hello\"", null ) );
|
||||||
|
assertEquals( "null", UIDefaultsLoader.parseValue( "dummy", "\"null\"", null ) );
|
||||||
|
|
||||||
|
assertEquals( 'a', UIDefaultsLoader.parseValue( "dummyChar", "a", null ) );
|
||||||
|
assertEquals( 123, UIDefaultsLoader.parseValue( "dummy", "123", null ) );
|
||||||
|
assertEquals( 123, UIDefaultsLoader.parseValue( "dummyWidth", "123", null ) );
|
||||||
|
assertEquals( 1.23f, UIDefaultsLoader.parseValue( "dummy", "1.23", null ) );
|
||||||
|
assertEquals( 1.23f, UIDefaultsLoader.parseValue( "dummyWidth", "{float}1.23", null ) );
|
||||||
|
|
||||||
|
assertEquals( new Insets( 2,2,2,2 ), UIDefaultsLoader.parseValue( "dummyInsets", "2,2,2,2", null ) );
|
||||||
|
assertEquals( new Dimension( 2,2 ), UIDefaultsLoader.parseValue( "dummySize", "2,2", null ) );
|
||||||
|
assertEquals( new Color( 0xff0000 ), UIDefaultsLoader.parseValue( "dummy", "#f00", null ) );
|
||||||
|
assertEquals( new Color( 0xff0000 ), UIDefaultsLoader.parseValue( "dummyColor", "#f00", null ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void parseValueWithJavaType() {
|
||||||
|
assertEquals( null, UIDefaultsLoader.parseValue( "dummy", "null", String.class ) );
|
||||||
|
assertEquals( false, UIDefaultsLoader.parseValue( "dummy", "false", boolean.class ) );
|
||||||
|
assertEquals( true, UIDefaultsLoader.parseValue( "dummy", "true", Boolean.class ) );
|
||||||
|
|
||||||
|
assertEquals( "hello", UIDefaultsLoader.parseValue( "dummy", "hello", String.class ) );
|
||||||
|
assertEquals( "hello", UIDefaultsLoader.parseValue( "dummy", "\"hello\"", String.class ) );
|
||||||
|
assertEquals( "null", UIDefaultsLoader.parseValue( "dummy", "\"null\"", String.class ) );
|
||||||
|
assertEquals( null, UIDefaultsLoader.parseValue( "dummy", "null", String.class ) );
|
||||||
|
|
||||||
|
assertEquals( 'a', UIDefaultsLoader.parseValue( "dummy", "a", char.class ) );
|
||||||
|
assertEquals( 'a', UIDefaultsLoader.parseValue( "dummy", "a", Character.class ) );
|
||||||
|
assertEquals( 123, UIDefaultsLoader.parseValue( "dummy", "123", int.class ) );
|
||||||
|
assertEquals( 123, UIDefaultsLoader.parseValue( "dummy", "123", Integer.class ) );
|
||||||
|
assertEquals( 1.23f, UIDefaultsLoader.parseValue( "dummy", "1.23", float.class ) );
|
||||||
|
assertEquals( 1.23f, UIDefaultsLoader.parseValue( "dummy", "1.23", Float.class ) );
|
||||||
|
|
||||||
|
assertEquals( new Insets( 2,2,2,2 ), UIDefaultsLoader.parseValue( "dummy", "2,2,2,2", Insets.class ) );
|
||||||
|
assertEquals( new Dimension( 2,2 ), UIDefaultsLoader.parseValue( "dummy", "2,2", Dimension.class ) );
|
||||||
|
assertEquals( new Color( 0xff0000 ), UIDefaultsLoader.parseValue( "dummy", "#f00", Color.class ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -56,7 +56,8 @@ public class UIDefaultsLoaderAccessor
|
|||||||
Function<String, String> resolver )
|
Function<String, String> resolver )
|
||||||
{
|
{
|
||||||
ValueType[] resultValueType2 = new ValueType[1];
|
ValueType[] resultValueType2 = new ValueType[1];
|
||||||
Object result = UIDefaultsLoader.parseValue( key, value, resultValueType2, resolver, Collections.emptyList() );
|
Object result = UIDefaultsLoader.parseValue( key, value, null,
|
||||||
|
resultValueType2, resolver, Collections.emptyList() );
|
||||||
resultValueType[0] = resultValueType2[0];
|
resultValueType[0] = resultValueType2[0];
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user