diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatSplitPaneUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatSplitPaneUI.java index 16ec4eba..0395af4d 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatSplitPaneUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatSplitPaneUI.java @@ -23,6 +23,8 @@ import java.awt.Graphics; import java.awt.Insets; import java.awt.event.MouseEvent; import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.Map; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JSplitPane; @@ -32,6 +34,9 @@ import javax.swing.UIManager; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.basic.BasicSplitPaneDivider; import javax.swing.plaf.basic.BasicSplitPaneUI; +import com.formdev.flatlaf.FlatClientProperties; +import com.formdev.flatlaf.ui.FlatStyleSupport.Styleable; +import com.formdev.flatlaf.ui.FlatStyleSupport.UnknownStyleException; import com.formdev.flatlaf.util.UIScale; /** @@ -67,15 +72,25 @@ import com.formdev.flatlaf.util.UIScale; public class FlatSplitPaneUI extends BasicSplitPaneUI { - protected String arrowType; - protected Color oneTouchArrowColor; - protected Color oneTouchHoverArrowColor; - protected Color oneTouchPressedArrowColor; + @Styleable protected String arrowType; + @Styleable protected Color oneTouchArrowColor; + @Styleable protected Color oneTouchHoverArrowColor; + @Styleable protected Color oneTouchPressedArrowColor; + + private PropertyChangeListener propertyChangeListener; + private Map oldStyleValues; public static ComponentUI createUI( JComponent c ) { return new FlatSplitPaneUI(); } + @Override + public void installUI( JComponent c ) { + super.installUI( c ); + + applyStyle( FlatStyleSupport.getStyle( splitPane ) ); + } + @Override protected void installDefaults() { arrowType = UIManager.getString( "Component.arrowType" ); @@ -98,21 +113,68 @@ public class FlatSplitPaneUI oneTouchPressedArrowColor = null; } + @Override + protected void installListeners() { + super.installListeners(); + + propertyChangeListener = e -> { + switch( e.getPropertyName() ) { + case FlatClientProperties.COMPONENT_STYLE: + applyStyle( e.getNewValue() ); + splitPane.revalidate(); + splitPane.repaint(); + break; + } + }; + splitPane.addPropertyChangeListener( propertyChangeListener ); + } + + @Override + protected void uninstallListeners() { + super.uninstallListeners(); + + splitPane.removePropertyChangeListener( propertyChangeListener ); + propertyChangeListener = null; + } + @Override public BasicSplitPaneDivider createDefaultDivider() { return new FlatSplitPaneDivider( this ); } + /** + * @since TODO + */ + protected void applyStyle( Object style ) { + oldStyleValues = FlatStyleSupport.parseAndApply( oldStyleValues, style, this::applyStyleProperty ); + + if( divider instanceof FlatSplitPaneDivider ) + ((FlatSplitPaneDivider)divider).updateButtons(); + } + + /** + * @since TODO + */ + protected Object applyStyleProperty( String key, Object value ) { + try { + if( divider instanceof FlatSplitPaneDivider ) + return ((FlatSplitPaneDivider)divider).applyStyleProperty( key, value ); + } catch( UnknownStyleException ex ) { + // ignore + } + return FlatStyleSupport.applyToAnnotatedObject( this, key, value ); + } + //---- class FlatSplitPaneDivider ----------------------------------------- protected class FlatSplitPaneDivider extends BasicSplitPaneDivider { - protected final String style = UIManager.getString( "SplitPaneDivider.style" ); - protected final Color gripColor = UIManager.getColor( "SplitPaneDivider.gripColor" ); - protected final int gripDotCount = FlatUIUtils.getUIInt( "SplitPaneDivider.gripDotCount", 3 ); - protected final int gripDotSize = FlatUIUtils.getUIInt( "SplitPaneDivider.gripDotSize", 3 ); - protected final int gripGap = FlatUIUtils.getUIInt( "SplitPaneDivider.gripGap", 2 ); + @Styleable protected String style = UIManager.getString( "SplitPaneDivider.style" ); + @Styleable protected Color gripColor = UIManager.getColor( "SplitPaneDivider.gripColor" ); + @Styleable protected int gripDotCount = FlatUIUtils.getUIInt( "SplitPaneDivider.gripDotCount", 3 ); + @Styleable protected int gripDotSize = FlatUIUtils.getUIInt( "SplitPaneDivider.gripDotSize", 3 ); + @Styleable protected int gripGap = FlatUIUtils.getUIInt( "SplitPaneDivider.gripGap", 2 ); protected FlatSplitPaneDivider( BasicSplitPaneUI ui ) { super( ui ); @@ -120,6 +182,20 @@ public class FlatSplitPaneUI setLayout( new FlatDividerLayout() ); } + /** + * @since TODO + */ + protected Object applyStyleProperty( String key, Object value ) { + return FlatStyleSupport.applyToAnnotatedObject( this, key, value ); + } + + void updateButtons() { + if( leftButton instanceof FlatOneTouchButton ) + ((FlatOneTouchButton)leftButton).update(); + if( rightButton instanceof FlatOneTouchButton ) + ((FlatOneTouchButton)rightButton).update(); + } + @Override public void setDividerSize( int newSize ) { super.setDividerSize( UIScale.scale( newSize ) ); @@ -200,6 +276,11 @@ public class FlatSplitPaneUI this.left = left; } + protected void update() { + update( arrowType, oneTouchArrowColor, null, + oneTouchHoverArrowColor, null, oneTouchPressedArrowColor, null ); + } + @Override public int getDirection() { return (orientation == JSplitPane.VERTICAL_SPLIT) 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 ab9440f6..6f37a993 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 @@ -61,11 +61,13 @@ public class FlatStyleSupport * first parameter is the key, second the binary value; * the function must return the old value * @return map of old values modified by the given style, or {@code null} + * @throws UnknownStyleException on unknown style keys * @throws IllegalArgumentException on syntax errors * @throws ClassCastException if value type does not fit to expected type  */ public static Map parseAndApply( Map oldStyleValues, - Object style, BiFunction applyProperty ) throws IllegalArgumentException + Object style, BiFunction applyProperty ) + throws UnknownStyleException, IllegalArgumentException { // restore previous values if( oldStyleValues != null ) { @@ -170,11 +172,11 @@ public class FlatStyleSupport * @param key the name of the field * @param value the new value * @return the old value of the field - * @throws IllegalArgumentException if object does not have a annotated field with given name - * or if value type does not fit to expected type  + * @throws UnknownStyleException if object does not have a annotated field with given name + * @throws IllegalArgumentException if value type does not fit to expected type  */ public static Object applyToAnnotatedObject( Object obj, String key, Object value ) - throws IllegalArgumentException + throws UnknownStyleException, IllegalArgumentException { Class cls = obj.getClass(); @@ -203,19 +205,30 @@ public class FlatStyleSupport cls = cls.getSuperclass(); if( cls == null ) - throw newUnknownStyleException( key ); + throw new UnknownStyleException( key ); String superclassName = cls.getName(); if( superclassName.startsWith( "java." ) || superclassName.startsWith( "javax." ) ) - throw newUnknownStyleException( key ); + throw new UnknownStyleException( key ); } } - public static IllegalArgumentException newUnknownStyleException( String key ) { - return new IllegalArgumentException( "unknown style '" + key + "'" ); - } - public static Object getStyle( JComponent c ) { return c.getClientProperty( FlatClientProperties.COMPONENT_STYLE ); } + + //---- class UnknownStyleException ---------------------------------------- + + public static class UnknownStyleException + extends IllegalArgumentException + { + UnknownStyleException( String key ) { + super( key ); + } + + @Override + public String getMessage() { + return "unknown style '" + super.getMessage() + "'"; + } + } } diff --git a/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/FlatStylingTests.java b/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/FlatStylingTests.java index 6178d518..23780402 100644 --- a/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/FlatStylingTests.java +++ b/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/FlatStylingTests.java @@ -23,6 +23,7 @@ import java.util.HashMap; import java.util.Map; import javax.swing.JCheckBox; import javax.swing.JRadioButton; +import javax.swing.JSplitPane; import javax.swing.UIManager; import org.junit.jupiter.api.Test; import com.formdev.flatlaf.icons.FlatCheckBoxIcon; @@ -208,6 +209,25 @@ public class FlatStylingTests ui.applyStyle( "tickColor: #fff" ); } + @Test + void splitPane() { + FlatSplitPaneUI ui = new FlatSplitPaneUI(); + + // create divider and one-touch buttons + ui.installUI( new JSplitPane() ); + + ui.applyStyle( "arrowType: chevron" ); + ui.applyStyle( "oneTouchArrowColor: #fff" ); + ui.applyStyle( "oneTouchHoverArrowColor: #fff" ); + ui.applyStyle( "oneTouchPressedArrowColor: #fff" ); + + ui.applyStyle( "style: grip" ); + ui.applyStyle( "gripColor: #fff" ); + ui.applyStyle( "gripDotCount: 3" ); + ui.applyStyle( "gripDotSize: {integer}3" ); + ui.applyStyle( "gripGap: 2" ); + } + //---- icons -------------------------------------------------------------- @Test