diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/icons/FlatCheckBoxIcon.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/icons/FlatCheckBoxIcon.java index c74c6976..41106a9b 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/icons/FlatCheckBoxIcon.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/icons/FlatCheckBoxIcon.java @@ -27,6 +27,8 @@ import javax.swing.AbstractButton; import javax.swing.JComponent; import javax.swing.UIManager; import com.formdev.flatlaf.ui.FlatButtonUI; +import com.formdev.flatlaf.ui.FlatStyleSupport; +import com.formdev.flatlaf.ui.FlatStyleSupport.Styleable; import com.formdev.flatlaf.ui.FlatUIUtils; /** @@ -67,39 +69,39 @@ public class FlatCheckBoxIcon extends FlatAbstractIcon { protected final String style = UIManager.getString( "CheckBox.icon.style" ); - public final int focusWidth = getUIInt( "CheckBox.icon.focusWidth", + @Styleable public int focusWidth = getUIInt( "CheckBox.icon.focusWidth", UIManager.getInt( "Component.focusWidth" ), style ); - protected final Color focusColor = FlatUIUtils.getUIColor( "CheckBox.icon.focusColor", + @Styleable protected Color focusColor = FlatUIUtils.getUIColor( "CheckBox.icon.focusColor", UIManager.getColor( "Component.focusColor" ) ); - protected final int arc = FlatUIUtils.getUIInt( "CheckBox.arc", 2 ); + @Styleable protected int arc = FlatUIUtils.getUIInt( "CheckBox.arc", 2 ); // enabled - protected final Color borderColor = getUIColor( "CheckBox.icon.borderColor", style ); - protected final Color background = getUIColor( "CheckBox.icon.background", style ); - protected final Color selectedBorderColor = getUIColor( "CheckBox.icon.selectedBorderColor", style ); - protected final Color selectedBackground = getUIColor( "CheckBox.icon.selectedBackground", style ); - protected final Color checkmarkColor = getUIColor( "CheckBox.icon.checkmarkColor", style ); + @Styleable protected Color borderColor = getUIColor( "CheckBox.icon.borderColor", style ); + @Styleable protected Color background = getUIColor( "CheckBox.icon.background", style ); + @Styleable protected Color selectedBorderColor = getUIColor( "CheckBox.icon.selectedBorderColor", style ); + @Styleable protected Color selectedBackground = getUIColor( "CheckBox.icon.selectedBackground", style ); + @Styleable protected Color checkmarkColor = getUIColor( "CheckBox.icon.checkmarkColor", style ); // disabled - protected final Color disabledBorderColor = getUIColor( "CheckBox.icon.disabledBorderColor", style ); - protected final Color disabledBackground = getUIColor( "CheckBox.icon.disabledBackground", style ); - protected final Color disabledCheckmarkColor = getUIColor( "CheckBox.icon.disabledCheckmarkColor", style ); + @Styleable protected Color disabledBorderColor = getUIColor( "CheckBox.icon.disabledBorderColor", style ); + @Styleable protected Color disabledBackground = getUIColor( "CheckBox.icon.disabledBackground", style ); + @Styleable protected Color disabledCheckmarkColor = getUIColor( "CheckBox.icon.disabledCheckmarkColor", style ); // focused - protected final Color focusedBorderColor = getUIColor( "CheckBox.icon.focusedBorderColor", style ); - protected final Color focusedBackground = getUIColor( "CheckBox.icon.focusedBackground", style ); - protected final Color selectedFocusedBorderColor = getUIColor( "CheckBox.icon.selectedFocusedBorderColor", style ); - protected final Color selectedFocusedBackground = getUIColor( "CheckBox.icon.selectedFocusedBackground", style ); - protected final Color selectedFocusedCheckmarkColor = getUIColor( "CheckBox.icon.selectedFocusedCheckmarkColor", style ); + @Styleable protected Color focusedBorderColor = getUIColor( "CheckBox.icon.focusedBorderColor", style ); + @Styleable protected Color focusedBackground = getUIColor( "CheckBox.icon.focusedBackground", style ); + @Styleable protected Color selectedFocusedBorderColor = getUIColor( "CheckBox.icon.selectedFocusedBorderColor", style ); + @Styleable protected Color selectedFocusedBackground = getUIColor( "CheckBox.icon.selectedFocusedBackground", style ); + @Styleable protected Color selectedFocusedCheckmarkColor = getUIColor( "CheckBox.icon.selectedFocusedCheckmarkColor", style ); // hover - protected final Color hoverBorderColor = getUIColor( "CheckBox.icon.hoverBorderColor", style ); - protected final Color hoverBackground = getUIColor( "CheckBox.icon.hoverBackground", style ); - protected final Color selectedHoverBackground = getUIColor( "CheckBox.icon.selectedHoverBackground", style ); + @Styleable protected Color hoverBorderColor = getUIColor( "CheckBox.icon.hoverBorderColor", style ); + @Styleable protected Color hoverBackground = getUIColor( "CheckBox.icon.hoverBackground", style ); + @Styleable protected Color selectedHoverBackground = getUIColor( "CheckBox.icon.selectedHoverBackground", style ); // pressed - protected final Color pressedBackground = getUIColor( "CheckBox.icon.pressedBackground", style ); - protected final Color selectedPressedBackground = getUIColor( "CheckBox.icon.selectedPressedBackground", style ); + @Styleable protected Color pressedBackground = getUIColor( "CheckBox.icon.pressedBackground", style ); + @Styleable protected Color selectedPressedBackground = getUIColor( "CheckBox.icon.selectedPressedBackground", style ); protected static Color getUIColor( String key, String style ) { if( style != null ) { @@ -129,6 +131,13 @@ public class FlatCheckBoxIcon super( ICON_SIZE, ICON_SIZE, null ); } + /** + * @since TODO + */ + public Object applyStyleProperty( String key, Object value ) { + return FlatStyleSupport.applyToAnnotatedObject( this, key, value ); + } + @Override protected void paintIcon( Component c, Graphics2D g ) { boolean indeterminate = isIndeterminate( c ); diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/icons/FlatRadioButtonIcon.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/icons/FlatRadioButtonIcon.java index 06095b0f..c26b1de6 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/icons/FlatRadioButtonIcon.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/icons/FlatRadioButtonIcon.java @@ -19,6 +19,7 @@ package com.formdev.flatlaf.icons; import java.awt.Component; import java.awt.Graphics2D; import java.awt.geom.Ellipse2D; +import com.formdev.flatlaf.ui.FlatStyleSupport.Styleable; /** * Icon for {@link javax.swing.JRadioButton}. @@ -34,7 +35,7 @@ import java.awt.geom.Ellipse2D; public class FlatRadioButtonIcon extends FlatCheckBoxIcon { - protected final int centerDiameter = getUIInt( "RadioButton.icon.centerDiameter", 8, style ); + @Styleable protected int centerDiameter = getUIInt( "RadioButton.icon.centerDiameter", 8, style ); @Override protected void paintFocusBorder( Component c, Graphics2D g ) { diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatRadioButtonUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatRadioButtonUI.java index 60f9cdaf..27da0e49 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatRadioButtonUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatRadioButtonUI.java @@ -68,6 +68,7 @@ public class FlatRadioButtonUI private Color defaultBackground; private final boolean shared; + private boolean iconShared; private boolean defaults_initialized = false; private Map oldStyleValues; @@ -82,6 +83,7 @@ public class FlatRadioButtonUI */ protected FlatRadioButtonUI( boolean shared ) { this.shared = shared; + iconShared = true; } @Override @@ -159,7 +161,24 @@ public class FlatRadioButtonUI * @since TODO */ protected Object applyStyleProperty( String key, Object value ) { - //TODO style icon + // style icon + if( key.startsWith( "icon." ) ) { + key = key.substring( "icon.".length() ); + + if( !(icon instanceof FlatCheckBoxIcon) ) + return null; + + if( iconShared ) { + try { + icon = icon.getClass().getDeclaredConstructor().newInstance(); + } catch( Exception ex ) { + throw new IllegalArgumentException( "failed to clone icon '" + icon.getClass().getName() + "'" ); + } + iconShared = false; + } + + return ((FlatCheckBoxIcon)icon).applyStyleProperty( key, value ); + } return FlatStyleSupport.applyToAnnotatedObject( this, key, value ); } 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 8f232bf4..28e979b4 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 @@ -17,16 +17,28 @@ package com.formdev.flatlaf.ui; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.awt.Color; import java.util.HashMap; import java.util.Map; +import javax.swing.JCheckBox; +import javax.swing.JRadioButton; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import com.formdev.flatlaf.FlatLightLaf; +import com.formdev.flatlaf.icons.FlatCheckBoxIcon; +import com.formdev.flatlaf.icons.FlatRadioButtonIcon; /** * @author Karl Tauber */ public class FlatStylingTests { + @BeforeAll + static void setup() { + FlatLightLaf.setup(); + } + @Test void parse() { assertEquals( null, FlatStyleSupport.parse( null ) ); @@ -53,18 +65,65 @@ public class FlatStylingTests return map; } - @Test - void checkbox() { - FlatCheckBoxUI ui = new FlatCheckBoxUI( false ); + //---- components --------------------------------------------------------- - ui.applyStyle( "disabledText: #fff" ); + @Test + void checkBox() { + FlatCheckBoxUI ui = new FlatCheckBoxUI( false ); + ui.installDefaults( new JCheckBox() ); // assign icon + assertTrue( ui.getDefaultIcon() instanceof FlatCheckBoxIcon ); + + // FlatCheckBoxUI extends FlatRadioButtonUI + radioButton( ui ); } @Test - void radiobutton() { + void radioButton() { FlatRadioButtonUI ui = new FlatRadioButtonUI( false ); + ui.installDefaults( new JRadioButton() ); // assign icon + assertTrue( ui.getDefaultIcon() instanceof FlatRadioButtonIcon ); + radioButton( ui ); + + ui.applyStyle( "icon.centerDiameter: 8" ); + } + + private void radioButton( FlatRadioButtonUI ui ) { ui.applyStyle( "disabledText: #fff" ); + + //---- icon ---- + + ui.applyStyle( "icon.focusWidth: 2" ); + ui.applyStyle( "icon.focusColor: #fff" ); + ui.applyStyle( "icon.arc: 5" ); + + // enabled + ui.applyStyle( "icon.borderColor: #fff" ); + ui.applyStyle( "icon.background: #fff" ); + ui.applyStyle( "icon.selectedBorderColor: #fff" ); + ui.applyStyle( "icon.selectedBackground: #fff" ); + ui.applyStyle( "icon.checkmarkColor: #fff" ); + + // disabled + ui.applyStyle( "icon.disabledBorderColor: #fff" ); + ui.applyStyle( "icon.disabledBackground: #fff" ); + ui.applyStyle( "icon.disabledCheckmarkColor: #fff" ); + + // focused + ui.applyStyle( "icon.focusedBorderColor: #fff" ); + ui.applyStyle( "icon.focusedBackground: #fff" ); + ui.applyStyle( "icon.selectedFocusedBorderColor: #fff" ); + ui.applyStyle( "icon.selectedFocusedBackground: #fff" ); + ui.applyStyle( "icon.selectedFocusedCheckmarkColor: #fff" ); + + // hover + ui.applyStyle( "icon.hoverBorderColor: #fff" ); + ui.applyStyle( "icon.hoverBackground: #fff" ); + ui.applyStyle( "icon.selectedHoverBackground: #fff" ); + + // pressed + ui.applyStyle( "icon.pressedBackground: #fff" ); + ui.applyStyle( "icon.selectedPressedBackground: #fff" ); } @Test @@ -88,4 +147,57 @@ public class FlatStylingTests ui.applyStyle( "disabledThumbBorderColor: #fff" ); ui.applyStyle( "tickColor: #fff" ); } + + //---- icons -------------------------------------------------------------- + + @Test + void checkBoxIcon() { + FlatCheckBoxIcon icon = new FlatCheckBoxIcon(); + + checkBoxIcon( icon ); + } + + @Test + void radioButtonIcon() { + FlatRadioButtonIcon icon = new FlatRadioButtonIcon(); + + // FlatRadioButtonIcon extends FlatCheckBoxIcon + checkBoxIcon( icon ); + + icon.applyStyleProperty( "centerDiameter", 8 ); + } + + private void checkBoxIcon( FlatCheckBoxIcon icon ) { + icon.applyStyleProperty( "focusWidth", 2 ); + icon.applyStyleProperty( "focusColor", Color.WHITE ); + icon.applyStyleProperty( "arc", 5 ); + + // enabled + icon.applyStyleProperty( "borderColor", Color.WHITE ); + icon.applyStyleProperty( "background", Color.WHITE ); + icon.applyStyleProperty( "selectedBorderColor", Color.WHITE ); + icon.applyStyleProperty( "selectedBackground", Color.WHITE ); + icon.applyStyleProperty( "checkmarkColor", Color.WHITE ); + + // disabled + icon.applyStyleProperty( "disabledBorderColor", Color.WHITE ); + icon.applyStyleProperty( "disabledBackground", Color.WHITE ); + icon.applyStyleProperty( "disabledCheckmarkColor", Color.WHITE ); + + // focused + icon.applyStyleProperty( "focusedBorderColor", Color.WHITE ); + icon.applyStyleProperty( "focusedBackground", Color.WHITE ); + icon.applyStyleProperty( "selectedFocusedBorderColor", Color.WHITE ); + icon.applyStyleProperty( "selectedFocusedBackground", Color.WHITE ); + icon.applyStyleProperty( "selectedFocusedCheckmarkColor", Color.WHITE ); + + // hover + icon.applyStyleProperty( "hoverBorderColor", Color.WHITE ); + icon.applyStyleProperty( "hoverBackground", Color.WHITE ); + icon.applyStyleProperty( "selectedHoverBackground", Color.WHITE ); + + // pressed + icon.applyStyleProperty( "pressedBackground", Color.WHITE ); + icon.applyStyleProperty( "selectedPressedBackground", Color.WHITE ); + } }