From c99be13697ad5d3802079231dcf0df3d73dd74ff Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Tue, 15 Jun 2021 23:23:11 +0200 Subject: [PATCH] Styling: support using `java.util.Map` as style e.g. `mySlider.putClientProperty( "JComponent.style", Collections.singletonMap( "thumbSize", new Dimension( 8, 24 ) ) );` --- .../formdev/flatlaf/FlatClientProperties.java | 2 +- .../com/formdev/flatlaf/ui/FlatSliderUI.java | 6 +- .../formdev/flatlaf/ui/FlatStyleSupport.java | 77 ++++++++++++++----- 3 files changed, 61 insertions(+), 24 deletions(-) diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java index 5318773d..67728871 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java @@ -130,7 +130,7 @@ public interface FlatClientProperties * Specifies the style of a component in CSS syntax ("key1: value1; key2: value2; ..."). *

* Components {@link javax.swing.JComponent}
- * Value type {@link java.lang.String}
+ * Value type {@link java.lang.String} or {@link java.util.Map}<String, Object>
* * @since TODO */ diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatSliderUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatSliderUI.java index 2c0b31ba..8bf7ea23 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatSliderUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatSliderUI.java @@ -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 ); } /** diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatStyleSupport.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatStyleSupport.java index 6ae189e4..95af2920 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatStyleSupport.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatStyleSupport.java @@ -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 parse( Map oldStyleValues, - String style, BiFunction applyProperty ) throws IllegalArgumentException + public static Map parseAndApply( Map oldStyleValues, + Object style, BiFunction applyProperty ) throws IllegalArgumentException { // restore previous values if( oldStyleValues != null ) { - for( Entry e : oldStyleValues.entrySet() ) + for( Map.Entry 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 map = (Map) style; + return applyStyle( map, applyProperty ); + } else + return null; + } + + private static Map applyStyle( Map style, + BiFunction applyProperty ) + { + if( style.isEmpty() ) + return null; + + Map oldValues = new HashMap<>(); + for( Map.Entry 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 parse( String style ) + throws IllegalArgumentException + { if( style == null || style.trim().isEmpty() ) return null; - Map oldValues = null; + Map 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 ); } }