Styling: support using java.util.Map as style

e.g. `mySlider.putClientProperty( "JComponent.style", Collections.singletonMap( "thumbSize", new Dimension( 8, 24 ) ) );`
This commit is contained in:
Karl Tauber
2021-06-15 23:23:11 +02:00
parent 0830c78728
commit c99be13697
3 changed files with 61 additions and 24 deletions

View File

@@ -130,7 +130,7 @@ public interface FlatClientProperties
* Specifies the style of a component in CSS syntax ("key1: value1; key2: value2; ...").
* <p>
* <strong>Components</strong> {@link javax.swing.JComponent}<br>
* <strong>Value type</strong> {@link java.lang.String}<br>
* <strong>Value type</strong> {@link java.lang.String} or {@link java.util.Map}&lt;String, Object&gt;<br>
*
* @since TODO
*/

View File

@@ -190,7 +190,7 @@ public class FlatSliderUI
switch( e.getPropertyName() ) {
case FlatClientProperties.COMPONENT_STYLE:
applyStyle( FlatStyleSupport.toString( e.getNewValue() ) );
applyStyle( e.getNewValue() );
slider.revalidate();
slider.repaint();
break;
@@ -201,8 +201,8 @@ public class FlatSliderUI
/**
* @since TODO
*/
protected void applyStyle( String style ) {
oldStyleValues = FlatStyleSupport.parse( oldStyleValues, style, this::applyStyleProperty );
protected void applyStyle( Object style ) {
oldStyleValues = FlatStyleSupport.parseAndApply( oldStyleValues, style, this::applyStyleProperty );
}
/**

View File

@@ -17,8 +17,8 @@
package com.formdev.flatlaf.ui;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.function.BiFunction;
import javax.swing.JComponent;
import javax.swing.UIManager;
@@ -40,7 +40,7 @@ public class FlatStyleSupport
* to apply the properties.
*
* @param oldStyleValues map of old values modified by the previous invocation, or {@code null}
* @param style the style in CSS syntax
* @param style the style in CSS syntax as string, or a Map, or {@code null}
* @param applyProperty function that is invoked to apply the properties;
* first parameter is the key, second the binary value;
* the function must return the old value
@@ -48,20 +48,67 @@ public class FlatStyleSupport
* @throws IllegalArgumentException on syntax errors
* @throws ClassCastException if value type does not fit to expected type 
*/
public static Map<String, Object> parse( Map<String, Object> oldStyleValues,
String style, BiFunction<String, Object, Object> applyProperty ) throws IllegalArgumentException
public static Map<String, Object> parseAndApply( Map<String, Object> oldStyleValues,
Object style, BiFunction<String, Object, Object> applyProperty ) throws IllegalArgumentException
{
// restore previous values
if( oldStyleValues != null ) {
for( Entry<String, Object> e : oldStyleValues.entrySet() )
for( Map.Entry<String, Object> e : oldStyleValues.entrySet() )
applyProperty.apply( e.getKey(), e.getValue() );
}
// ignore empty style
if( style == null )
return null;
if( style instanceof String ) {
// handle style in CSS syntax
String str = (String) style;
if( str.trim().isEmpty() )
return null;
return applyStyle( parse( str ), applyProperty );
} else if( style instanceof Map ) {
// handle style of type Map
@SuppressWarnings( "unchecked" )
Map<String, Object> map = (Map<String, Object>) style;
return applyStyle( map, applyProperty );
} else
return null;
}
private static Map<String, Object> applyStyle( Map<String, Object> style,
BiFunction<String, Object, Object> applyProperty )
{
if( style.isEmpty() )
return null;
Map<String, Object> oldValues = new HashMap<>();
for( Map.Entry<String, Object> e : style.entrySet() ) {
String key = e.getKey();
Object newValue = e.getValue();
Object oldValue = applyProperty.apply( key, newValue );
oldValues.put( key, oldValue );
}
return oldValues;
}
/**
* Parses styles in CSS syntax ("key1: value1; key2: value2; ..."),
* converts the value strings into binary and returns all key/value pairs as map.
*
* @param style the style in CSS syntax, or {@code null}
* @return map of parsed styles, or {@code null}
* @throws IllegalArgumentException on syntax errors
*/
public static Map<String, Object> parse( String style )
throws IllegalArgumentException
{
if( style == null || style.trim().isEmpty() )
return null;
Map<String, Object> oldValues = null;
Map<String, Object> map = new LinkedHashMap<>();
// split style into parts and process them
for( String part : StringUtils.split( style, ';' ) ) {
@@ -84,16 +131,10 @@ public class FlatStyleSupport
throw new IllegalArgumentException( "missing value in '" + part + "'" );
// parse value string and convert it into binary value
Object newValue = parseValue( key, value );
Object oldValue = applyProperty.apply( key, newValue );
// remember previous value
if( oldValues == null )
oldValues = new HashMap<>();
oldValues.put( key, oldValue );
map.put( key, parseValue( key, value ) );
}
return oldValues;
return map;
}
private static Object parseValue( String key, String value ) {
@@ -107,11 +148,7 @@ public class FlatStyleSupport
return getStyle( c ) != null;
}
public static String getStyle( JComponent c ) {
return toString( c.getClientProperty( FlatClientProperties.COMPONENT_STYLE ) );
}
static String toString( Object style ) {
return (style instanceof String) ? (String) style : null;
public static Object getStyle( JComponent c ) {
return c.getClientProperty( FlatClientProperties.COMPONENT_STYLE );
}
}