diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f724e85..27a602ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ FlatLaf Change Log #### New features and improvements +- CheckBox: Support styling indeterminate state of + [tri-state check boxes](https://www.javadoc.io/doc/com.formdev/flatlaf-extras/latest/com/formdev/flatlaf/extras/components/FlatTriStateCheckBox.html). + (issue #919) - Tree: Support for alternate row highlighting. (PR #903) - Tree: Support wide cell renderer. (issue #922) - Extras: `FlatSVGIcon` color filters now can access painting component to 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 28afd50a..f2fa0254 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 @@ -17,6 +17,7 @@ package com.formdev.flatlaf.icons; import static com.formdev.flatlaf.FlatClientProperties.*; +import static com.formdev.flatlaf.ui.FlatUIUtils.stateColor; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Component; @@ -48,6 +49,8 @@ import com.formdev.flatlaf.ui.FlatUIUtils; * @uiDefault CheckBox.icon.borderWidth int or float optional; defaults to Component.borderWidth * @uiDefault CheckBox.icon.selectedBorderWidth int or float optional; defaults to CheckBox.icon.borderWidth * @uiDefault CheckBox.icon.disabledSelectedBorderWidth int or float optional; defaults to CheckBox.icon.selectedBorderWidth + * @uiDefault CheckBox.icon.indeterminateBorderWidth int or float optional; defaults to CheckBox.icon.selectedBorderWidth + * @uiDefault CheckBox.icon.disabledIndeterminateBorderWidth int or float optional; defaults to CheckBox.icon.disabledSelectedBorderWidth * @uiDefault CheckBox.arc int * * @uiDefault CheckBox.icon.focusColor Color optional; defaults to Component.focusColor @@ -56,30 +59,45 @@ import com.formdev.flatlaf.ui.FlatUIUtils; * @uiDefault CheckBox.icon.selectedBorderColor Color * @uiDefault CheckBox.icon.selectedBackground Color * @uiDefault CheckBox.icon.checkmarkColor Color + * @uiDefault CheckBox.icon.indeterminateBorderColor Color optional; defaults to CheckBox.icon.selectedBorderColor + * @uiDefault CheckBox.icon.indeterminateBackground Color optional; defaults to CheckBox.icon.selectedBackground + * @uiDefault CheckBox.icon.indeterminateCheckmarkColor Color optional; defaults to CheckBox.icon.checkmarkColor * - * @uiDefault CheckBox.icon.disabledBorderColor Color - * @uiDefault CheckBox.icon.disabledBackground Color - * @uiDefault CheckBox.icon.disabledSelectedBorderColor Color optional; CheckBox.icon.disabledBorderColor is used if not specified - * @uiDefault CheckBox.icon.disabledSelectedBackground Color optional; CheckBox.icon.disabledBackground is used if not specified - * @uiDefault CheckBox.icon.disabledCheckmarkColor Color + * @uiDefault CheckBox.icon.disabledBorderColor Color + * @uiDefault CheckBox.icon.disabledBackground Color + * @uiDefault CheckBox.icon.disabledSelectedBorderColor Color optional; defaults to CheckBox.icon.disabledBorderColor + * @uiDefault CheckBox.icon.disabledSelectedBackground Color optional; defaults to CheckBox.icon.disabledBackground + * @uiDefault CheckBox.icon.disabledCheckmarkColor Color + * @uiDefault CheckBox.icon.disabledIndeterminateBorderColor Color optional; defaults to CheckBox.icon.disabledSelectedBorderColor + * @uiDefault CheckBox.icon.disabledIndeterminateBackground Color optional; defaults to CheckBox.icon.disabledSelectedBackground + * @uiDefault CheckBox.icon.disabledIndeterminateCheckmarkColor Color optional; defaults to CheckBox.icon.disabledCheckmarkColor * - * @uiDefault CheckBox.icon.focusedBorderColor Color optional - * @uiDefault CheckBox.icon.focusedBackground Color optional - * @uiDefault CheckBox.icon.focusedSelectedBorderColor Color optional; CheckBox.icon.focusedBorderColor is used if not specified - * @uiDefault CheckBox.icon.focusedSelectedBackground Color optional; CheckBox.icon.focusedBackground is used if not specified - * @uiDefault CheckBox.icon.focusedCheckmarkColor Color optional; CheckBox.icon.checkmarkColor is used if not specified + * @uiDefault CheckBox.icon.focusedBorderColor Color optional + * @uiDefault CheckBox.icon.focusedBackground Color optional + * @uiDefault CheckBox.icon.focusedSelectedBorderColor Color optional; defaults to CheckBox.icon.focusedBorderColor + * @uiDefault CheckBox.icon.focusedSelectedBackground Color optional; defaults to CheckBox.icon.focusedBackground + * @uiDefault CheckBox.icon.focusedCheckmarkColor Color optional; defaults to CheckBox.icon.checkmarkColor + * @uiDefault CheckBox.icon.focusedIndeterminateBorderColor Color optional; defaults to CheckBox.icon.focusedSelectedBorderColor + * @uiDefault CheckBox.icon.focusedIndeterminateBackground Color optional; defaults to CheckBox.icon.focusedSelectedBackground + * @uiDefault CheckBox.icon.focusedIndeterminateCheckmarkColor Color optional; defaults to CheckBox.icon.focusedCheckmarkColor * - * @uiDefault CheckBox.icon.hoverBorderColor Color optional - * @uiDefault CheckBox.icon.hoverBackground Color optional - * @uiDefault CheckBox.icon.hoverSelectedBorderColor Color optional; CheckBox.icon.hoverBorderColor is used if not specified - * @uiDefault CheckBox.icon.hoverSelectedBackground Color optional; CheckBox.icon.hoverBackground is used if not specified - * @uiDefault CheckBox.icon.hoverCheckmarkColor Color optional; CheckBox.icon.checkmarkColor is used if not specified + * @uiDefault CheckBox.icon.hoverBorderColor Color optional + * @uiDefault CheckBox.icon.hoverBackground Color optional + * @uiDefault CheckBox.icon.hoverSelectedBorderColor Color optional; defaults to CheckBox.icon.hoverBorderColor + * @uiDefault CheckBox.icon.hoverSelectedBackground Color optional; defaults to CheckBox.icon.hoverBackground + * @uiDefault CheckBox.icon.hoverCheckmarkColor Color optional; defaults to CheckBox.icon.checkmarkColor + * @uiDefault CheckBox.icon.hoverIndeterminateBorderColor Color optional; defaults to CheckBox.icon.hoverSelectedBorderColor + * @uiDefault CheckBox.icon.hoverIndeterminateBackground Color optional; defaults to CheckBox.icon.hoverSelectedBackground + * @uiDefault CheckBox.icon.hoverIndeterminateCheckmarkColor Color optional; defaults to CheckBox.icon.hoverCheckmarkColor * - * @uiDefault CheckBox.icon.pressedBorderColor Color optional - * @uiDefault CheckBox.icon.pressedBackground Color optional - * @uiDefault CheckBox.icon.pressedSelectedBorderColor Color optional; CheckBox.icon.pressedBorderColor is used if not specified - * @uiDefault CheckBox.icon.pressedSelectedBackground Color optional; CheckBox.icon.pressedBackground is used if not specified - * @uiDefault CheckBox.icon.pressedCheckmarkColor Color optional; CheckBox.icon.checkmarkColor is used if not specified + * @uiDefault CheckBox.icon.pressedBorderColor Color optional + * @uiDefault CheckBox.icon.pressedBackground Color optional + * @uiDefault CheckBox.icon.pressedSelectedBorderColor Color optional; defaults to CheckBox.icon.pressedBorderColor + * @uiDefault CheckBox.icon.pressedSelectedBackground Color optional; defaults to CheckBox.icon.pressedBackground + * @uiDefault CheckBox.icon.pressedCheckmarkColor Color optional; defaults to CheckBox.icon.checkmarkColor + * @uiDefault CheckBox.icon.pressedIndeterminateBorderColor Color optional; defaults to CheckBox.icon.pressedSelectedBorderColor + * @uiDefault CheckBox.icon.pressedIndeterminateBackground Color optional; defaults to CheckBox.icon.pressedSelectedBackground + * @uiDefault CheckBox.icon.pressedIndeterminateCheckmarkColor Color optional; defaults to CheckBox.icon.pressedCheckmarkColor * * @author Karl Tauber */ @@ -92,6 +110,8 @@ public class FlatCheckBoxIcon /** @since 2 */ @Styleable protected float borderWidth = getUIFloat( "CheckBox.icon.borderWidth", FlatUIUtils.getUIFloat( "Component.borderWidth", 1 ), style ); /** @since 2 */ @Styleable protected float selectedBorderWidth = getUIFloat( "CheckBox.icon.selectedBorderWidth", Float.MIN_VALUE, style ); /** @since 2 */ @Styleable protected float disabledSelectedBorderWidth = getUIFloat( "CheckBox.icon.disabledSelectedBorderWidth", Float.MIN_VALUE, style ); + /** @since 3.6 */ @Styleable protected float indeterminateBorderWidth = getUIFloat( "CheckBox.icon.indeterminateBorderWidth", Float.MIN_VALUE, style ); + /** @since 3.6 */ @Styleable protected float disabledIndeterminateBorderWidth = getUIFloat( "CheckBox.icon.disabledIndeterminateBorderWidth", Float.MIN_VALUE, style ); @Styleable protected int arc = FlatUIUtils.getUIInt( "CheckBox.arc", 2 ); // enabled @@ -100,6 +120,9 @@ public class FlatCheckBoxIcon @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 ); + /** @since 3.6 */ @Styleable protected Color indeterminateBorderColor = getUIColor( "CheckBox.icon.indeterminateBorderColor", style ); + /** @since 3.6 */ @Styleable protected Color indeterminateBackground = getUIColor( "CheckBox.icon.indeterminateBackground", style ); + /** @since 3.6 */ @Styleable protected Color indeterminateCheckmarkColor = getUIColor( "CheckBox.icon.indeterminateCheckmarkColor", style ); // disabled @Styleable protected Color disabledBorderColor = getUIColor( "CheckBox.icon.disabledBorderColor", style ); @@ -107,6 +130,9 @@ public class FlatCheckBoxIcon /** @since 2 */ @Styleable protected Color disabledSelectedBorderColor = getUIColor( "CheckBox.icon.disabledSelectedBorderColor", style ); /** @since 2 */ @Styleable protected Color disabledSelectedBackground = getUIColor( "CheckBox.icon.disabledSelectedBackground", style ); @Styleable protected Color disabledCheckmarkColor = getUIColor( "CheckBox.icon.disabledCheckmarkColor", style ); + /** @since 3.6 */ @Styleable protected Color disabledIndeterminateBorderColor = getUIColor( "CheckBox.icon.disabledIndeterminateBorderColor", style ); + /** @since 3.6 */ @Styleable protected Color disabledIndeterminateBackground = getUIColor( "CheckBox.icon.disabledIndeterminateBackground", style ); + /** @since 3.6 */ @Styleable protected Color disabledIndeterminateCheckmarkColor = getUIColor( "CheckBox.icon.disabledIndeterminateCheckmarkColor", style ); // focused @Styleable protected Color focusedBorderColor = getUIColor( "CheckBox.icon.focusedBorderColor", style ); @@ -114,6 +140,9 @@ public class FlatCheckBoxIcon /** @since 2 */ @Styleable protected Color focusedSelectedBorderColor = getUIColor( "CheckBox.icon.focusedSelectedBorderColor", style ); /** @since 2 */ @Styleable protected Color focusedSelectedBackground = getUIColor( "CheckBox.icon.focusedSelectedBackground", style ); /** @since 2 */ @Styleable protected Color focusedCheckmarkColor = getUIColor( "CheckBox.icon.focusedCheckmarkColor", style ); + /** @since 3.6 */ @Styleable protected Color focusedIndeterminateBorderColor = getUIColor( "CheckBox.icon.focusedIndeterminateBorderColor", style ); + /** @since 3.6 */ @Styleable protected Color focusedIndeterminateBackground = getUIColor( "CheckBox.icon.focusedIndeterminateBackground", style ); + /** @since 3.6 */ @Styleable protected Color focusedIndeterminateCheckmarkColor = getUIColor( "CheckBox.icon.focusedIndeterminateCheckmarkColor", style ); // hover @Styleable protected Color hoverBorderColor = getUIColor( "CheckBox.icon.hoverBorderColor", style ); @@ -121,6 +150,9 @@ public class FlatCheckBoxIcon /** @since 2 */ @Styleable protected Color hoverSelectedBorderColor = getUIColor( "CheckBox.icon.hoverSelectedBorderColor", style ); /** @since 2 */ @Styleable protected Color hoverSelectedBackground = getUIColor( "CheckBox.icon.hoverSelectedBackground", style ); /** @since 2 */ @Styleable protected Color hoverCheckmarkColor = getUIColor( "CheckBox.icon.hoverCheckmarkColor", style ); + /** @since 3.6 */ @Styleable protected Color hoverIndeterminateBorderColor = getUIColor( "CheckBox.icon.hoverIndeterminateBorderColor", style ); + /** @since 3.6 */ @Styleable protected Color hoverIndeterminateBackground = getUIColor( "CheckBox.icon.hoverIndeterminateBackground", style ); + /** @since 3.6 */ @Styleable protected Color hoverIndeterminateCheckmarkColor = getUIColor( "CheckBox.icon.hoverIndeterminateCheckmarkColor", style ); // pressed /** @since 2 */ @Styleable protected Color pressedBorderColor = getUIColor( "CheckBox.icon.pressedBorderColor", style ); @@ -128,6 +160,9 @@ public class FlatCheckBoxIcon /** @since 2 */ @Styleable protected Color pressedSelectedBorderColor = getUIColor( "CheckBox.icon.pressedSelectedBorderColor", style ); /** @since 2 */ @Styleable protected Color pressedSelectedBackground = getUIColor( "CheckBox.icon.pressedSelectedBackground", style ); /** @since 2 */ @Styleable protected Color pressedCheckmarkColor = getUIColor( "CheckBox.icon.pressedCheckmarkColor", style ); + /** @since 3.6 */ @Styleable protected Color pressedIndeterminateBorderColor = getUIColor( "CheckBox.icon.pressedIndeterminateBorderColor", style ); + /** @since 3.6 */ @Styleable protected Color pressedIndeterminateBackground = getUIColor( "CheckBox.icon.pressedIndeterminateBackground", style ); + /** @since 3.6 */ @Styleable protected Color pressedIndeterminateCheckmarkColor = getUIColor( "CheckBox.icon.pressedIndeterminateCheckmarkColor", style ); protected String getPropertyPrefix() { return "CheckBox."; @@ -182,11 +217,17 @@ public class FlatCheckBoxIcon boolean indeterminate = isIndeterminate( c ); boolean selected = indeterminate || isSelected( c ); boolean isFocused = FlatUIUtils.isPermanentFocusOwner( c ); - float bw = selected - ? (disabledSelectedBorderWidth != Float.MIN_VALUE && !c.isEnabled() - ? disabledSelectedBorderWidth - : (selectedBorderWidth != Float.MIN_VALUE ? selectedBorderWidth : borderWidth)) - : borderWidth; + float bw = Float.MIN_VALUE; + if( !c.isEnabled() ) { + bw = (indeterminate && disabledIndeterminateBorderWidth != Float.MIN_VALUE) + ? disabledIndeterminateBorderWidth + : (selected ? disabledSelectedBorderWidth : selectedBorderWidth); + } + if( bw == Float.MIN_VALUE ) { + bw = (indeterminate && indeterminateBorderWidth != Float.MIN_VALUE) + ? indeterminateBorderWidth + : ((selected && selectedBorderWidth != Float.MIN_VALUE) ? selectedBorderWidth : borderWidth); + } // paint focused border if( isFocused && focusWidth > 0 && FlatButtonUI.isFocusPainted( c ) ) { @@ -195,15 +236,15 @@ public class FlatCheckBoxIcon } // paint border - g.setColor( getBorderColor( c, selected ) ); + g.setColor( getBorderColor( c, selected, indeterminate ) ); paintBorder( c, g, bw ); // paint background - Color bg = FlatUIUtils.deriveColor( getBackground( c, selected ), - selected ? selectedBackground : background ); + Color baseBg = stateColor( indeterminate, indeterminateBackground, selected, selectedBackground, background ); + Color bg = FlatUIUtils.deriveColor( getBackground( c, selected, indeterminate ), baseBg ); if( bg.getAlpha() < 255 ) { // fill background with default color before filling with non-opaque background - g.setColor( selected ? selectedBackground : background ); + g.setColor( baseBg ); paintBackground( c, g, bw ); } g.setColor( bg ); @@ -211,7 +252,7 @@ public class FlatCheckBoxIcon // paint checkmark if( selected ) { - g.setColor( getCheckmarkColor( c ) ); + g.setColor( getCheckmarkColor( c, indeterminate ) ); if( indeterminate ) paintIndeterminate( c, g ); else @@ -272,30 +313,33 @@ public class FlatCheckBoxIcon return focusColor; } - protected Color getBorderColor( Component c, boolean selected ) { + /** @since 3.6 */ + protected Color getBorderColor( Component c, boolean selected, boolean indeterminate ) { return FlatButtonUI.buttonStateColor( c, - selected ? selectedBorderColor : borderColor, - (selected && disabledSelectedBorderColor != null) ? disabledSelectedBorderColor : disabledBorderColor, - (selected && focusedSelectedBorderColor != null) ? focusedSelectedBorderColor : focusedBorderColor, - (selected && hoverSelectedBorderColor != null) ? hoverSelectedBorderColor : hoverBorderColor, - (selected && pressedSelectedBorderColor != null) ? pressedSelectedBorderColor : pressedBorderColor ); + stateColor( indeterminate, indeterminateBorderColor, selected, selectedBorderColor, borderColor ), + stateColor( indeterminate, disabledIndeterminateBorderColor, selected, disabledSelectedBorderColor, disabledBorderColor ), + stateColor( indeterminate, focusedIndeterminateBorderColor, selected, focusedSelectedBorderColor, focusedBorderColor ), + stateColor( indeterminate, hoverIndeterminateBorderColor, selected, hoverSelectedBorderColor, hoverBorderColor ), + stateColor( indeterminate, pressedIndeterminateBorderColor, selected, pressedSelectedBorderColor, pressedBorderColor ) ); } - protected Color getBackground( Component c, boolean selected ) { + /** @since 3.6 */ + protected Color getBackground( Component c, boolean selected, boolean indeterminate ) { return FlatButtonUI.buttonStateColor( c, - selected ? selectedBackground : background, - (selected && disabledSelectedBackground != null) ? disabledSelectedBackground : disabledBackground, - (selected && focusedSelectedBackground != null) ? focusedSelectedBackground : focusedBackground, - (selected && hoverSelectedBackground != null) ? hoverSelectedBackground : hoverBackground, - (selected && pressedSelectedBackground != null) ? pressedSelectedBackground : pressedBackground ); + stateColor( indeterminate, indeterminateBackground, selected, selectedBackground, background ), + stateColor( indeterminate, disabledIndeterminateBackground, selected, disabledSelectedBackground, disabledBackground ), + stateColor( indeterminate, focusedIndeterminateBackground, selected, focusedSelectedBackground, focusedBackground ), + stateColor( indeterminate, hoverIndeterminateBackground, selected, hoverSelectedBackground, hoverBackground ), + stateColor( indeterminate, pressedIndeterminateBackground, selected, pressedSelectedBackground, pressedBackground ) ); } - protected Color getCheckmarkColor( Component c ) { + /** @since 3.6 */ + protected Color getCheckmarkColor( Component c, boolean indeterminate ) { return FlatButtonUI.buttonStateColor( c, - checkmarkColor, - disabledCheckmarkColor, - focusedCheckmarkColor, - hoverCheckmarkColor, - pressedCheckmarkColor ); + stateColor( indeterminate, indeterminateCheckmarkColor, checkmarkColor ), + stateColor( indeterminate, disabledIndeterminateCheckmarkColor, disabledCheckmarkColor ), + stateColor( indeterminate, focusedIndeterminateCheckmarkColor, focusedCheckmarkColor ), + stateColor( indeterminate, hoverIndeterminateCheckmarkColor, hoverCheckmarkColor ), + stateColor( indeterminate, pressedIndeterminateCheckmarkColor, pressedCheckmarkColor ) ); } } diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatUIUtils.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatUIUtils.java index b6cf2e95..706e4546 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatUIUtils.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatUIUtils.java @@ -129,6 +129,20 @@ public class FlatUIUtils return insets.top == 0 && insets.left == 0 && insets.bottom == 0 && insets.right == 0; } + /** @since 3.6 */ + public static Color stateColor( boolean state, Color stateColor, Color defaultColor ) { + return (state && stateColor != null) ? stateColor : defaultColor; + } + + /** @since 3.6 */ + public static Color stateColor( boolean state1, Color state1Color, + boolean state2, Color state2Color, Color defaultColor ) + { + return (state1 && state1Color != null) + ? state1Color + : ((state2 && state2Color != null) ? state2Color : defaultColor); + } + public static Color getUIColor( String key, int defaultColorRGB ) { Color color = UIManager.getColor( key ); return (color != null) ? color : new Color( defaultColorRGB ); diff --git a/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleableInfo.java b/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleableInfo.java index 596ac6c8..f6486896 100644 --- a/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleableInfo.java +++ b/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleableInfo.java @@ -517,6 +517,8 @@ public class TestFlatStyleableInfo "icon.borderWidth", float.class, "icon.selectedBorderWidth", float.class, "icon.disabledSelectedBorderWidth", float.class, + "icon.indeterminateBorderWidth", float.class, + "icon.disabledIndeterminateBorderWidth", float.class, "icon.arc", int.class, // enabled @@ -525,6 +527,9 @@ public class TestFlatStyleableInfo "icon.selectedBorderColor", Color.class, "icon.selectedBackground", Color.class, "icon.checkmarkColor", Color.class, + "icon.indeterminateBorderColor", Color.class, + "icon.indeterminateBackground", Color.class, + "icon.indeterminateCheckmarkColor", Color.class, // disabled "icon.disabledBorderColor", Color.class, @@ -532,6 +537,9 @@ public class TestFlatStyleableInfo "icon.disabledSelectedBorderColor", Color.class, "icon.disabledSelectedBackground", Color.class, "icon.disabledCheckmarkColor", Color.class, + "icon.disabledIndeterminateBorderColor", Color.class, + "icon.disabledIndeterminateBackground", Color.class, + "icon.disabledIndeterminateCheckmarkColor", Color.class, // focused "icon.focusedBorderColor", Color.class, @@ -539,6 +547,9 @@ public class TestFlatStyleableInfo "icon.focusedSelectedBorderColor", Color.class, "icon.focusedSelectedBackground", Color.class, "icon.focusedCheckmarkColor", Color.class, + "icon.focusedIndeterminateBorderColor", Color.class, + "icon.focusedIndeterminateBackground", Color.class, + "icon.focusedIndeterminateCheckmarkColor", Color.class, // hover "icon.hoverBorderColor", Color.class, @@ -546,13 +557,19 @@ public class TestFlatStyleableInfo "icon.hoverSelectedBorderColor", Color.class, "icon.hoverSelectedBackground", Color.class, "icon.hoverCheckmarkColor", Color.class, + "icon.hoverIndeterminateBorderColor", Color.class, + "icon.hoverIndeterminateBackground", Color.class, + "icon.hoverIndeterminateCheckmarkColor", Color.class, // pressed "icon.pressedBorderColor", Color.class, "icon.pressedBackground", Color.class, "icon.pressedSelectedBorderColor", Color.class, "icon.pressedSelectedBackground", Color.class, - "icon.pressedCheckmarkColor", Color.class + "icon.pressedCheckmarkColor", Color.class, + "icon.pressedIndeterminateBorderColor", Color.class, + "icon.pressedIndeterminateBackground", Color.class, + "icon.pressedIndeterminateCheckmarkColor", Color.class ); } @@ -1146,6 +1163,8 @@ public class TestFlatStyleableInfo "borderWidth", float.class, "selectedBorderWidth", float.class, "disabledSelectedBorderWidth", float.class, + "indeterminateBorderWidth", float.class, + "disabledIndeterminateBorderWidth", float.class, "arc", int.class, // enabled @@ -1154,6 +1173,9 @@ public class TestFlatStyleableInfo "selectedBorderColor", Color.class, "selectedBackground", Color.class, "checkmarkColor", Color.class, + "indeterminateBorderColor", Color.class, + "indeterminateBackground", Color.class, + "indeterminateCheckmarkColor", Color.class, // disabled "disabledBorderColor", Color.class, @@ -1161,6 +1183,9 @@ public class TestFlatStyleableInfo "disabledSelectedBorderColor", Color.class, "disabledSelectedBackground", Color.class, "disabledCheckmarkColor", Color.class, + "disabledIndeterminateBorderColor", Color.class, + "disabledIndeterminateBackground", Color.class, + "disabledIndeterminateCheckmarkColor", Color.class, // focused "focusedBorderColor", Color.class, @@ -1168,6 +1193,9 @@ public class TestFlatStyleableInfo "focusedSelectedBorderColor", Color.class, "focusedSelectedBackground", Color.class, "focusedCheckmarkColor", Color.class, + "focusedIndeterminateBorderColor", Color.class, + "focusedIndeterminateBackground", Color.class, + "focusedIndeterminateCheckmarkColor", Color.class, // hover "hoverBorderColor", Color.class, @@ -1175,13 +1203,19 @@ public class TestFlatStyleableInfo "hoverSelectedBorderColor", Color.class, "hoverSelectedBackground", Color.class, "hoverCheckmarkColor", Color.class, + "hoverIndeterminateBorderColor", Color.class, + "hoverIndeterminateBackground", Color.class, + "hoverIndeterminateCheckmarkColor", Color.class, // pressed "pressedBorderColor", Color.class, "pressedBackground", Color.class, "pressedSelectedBorderColor", Color.class, "pressedSelectedBackground", Color.class, - "pressedCheckmarkColor", Color.class + "pressedCheckmarkColor", Color.class, + "pressedIndeterminateBorderColor", Color.class, + "pressedIndeterminateBackground", Color.class, + "pressedIndeterminateCheckmarkColor", Color.class ); } diff --git a/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleableValue.java b/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleableValue.java index f0ae4484..3e4fb0fd 100644 --- a/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleableValue.java +++ b/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleableValue.java @@ -1148,6 +1148,8 @@ public class TestFlatStyleableValue testValue( icon, "borderWidth", 1.5f ); testValue( icon, "selectedBorderWidth", 1.5f ); testValue( icon, "disabledSelectedBorderWidth", 1.5f ); + testValue( icon, "indeterminateBorderWidth", 1.5f ); + testValue( icon, "disabledIndeterminateBorderWidth", 1.5f ); testValue( icon, "arc", 5 ); // enabled @@ -1156,6 +1158,9 @@ public class TestFlatStyleableValue testValue( icon, "selectedBorderColor", Color.WHITE ); testValue( icon, "selectedBackground", Color.WHITE ); testValue( icon, "checkmarkColor", Color.WHITE ); + testValue( icon, "indeterminateBorderColor", Color.WHITE ); + testValue( icon, "indeterminateBackground", Color.WHITE ); + testValue( icon, "indeterminateCheckmarkColor", Color.WHITE ); // disabled testValue( icon, "disabledBorderColor", Color.WHITE ); @@ -1163,6 +1168,9 @@ public class TestFlatStyleableValue testValue( icon, "disabledSelectedBorderColor", Color.WHITE ); testValue( icon, "disabledSelectedBackground", Color.WHITE ); testValue( icon, "disabledCheckmarkColor", Color.WHITE ); + testValue( icon, "disabledIndeterminateBorderColor", Color.WHITE ); + testValue( icon, "disabledIndeterminateBackground", Color.WHITE ); + testValue( icon, "disabledIndeterminateCheckmarkColor", Color.WHITE ); // focused testValue( icon, "focusedBorderColor", Color.WHITE ); @@ -1170,6 +1178,9 @@ public class TestFlatStyleableValue testValue( icon, "focusedSelectedBorderColor", Color.WHITE ); testValue( icon, "focusedSelectedBackground", Color.WHITE ); testValue( icon, "focusedCheckmarkColor", Color.WHITE ); + testValue( icon, "focusedIndeterminateBorderColor", Color.WHITE ); + testValue( icon, "focusedIndeterminateBackground", Color.WHITE ); + testValue( icon, "focusedIndeterminateCheckmarkColor", Color.WHITE ); // hover testValue( icon, "hoverBorderColor", Color.WHITE ); @@ -1177,6 +1188,9 @@ public class TestFlatStyleableValue testValue( icon, "hoverSelectedBorderColor", Color.WHITE ); testValue( icon, "hoverSelectedBackground", Color.WHITE ); testValue( icon, "hoverCheckmarkColor", Color.WHITE ); + testValue( icon, "hoverIndeterminateBorderColor", Color.WHITE ); + testValue( icon, "hoverIndeterminateBackground", Color.WHITE ); + testValue( icon, "hoverIndeterminateCheckmarkColor", Color.WHITE ); // pressed testValue( icon, "pressedBorderColor", Color.WHITE ); @@ -1184,6 +1198,9 @@ public class TestFlatStyleableValue testValue( icon, "pressedSelectedBorderColor", Color.WHITE ); testValue( icon, "pressedSelectedBackground", Color.WHITE ); testValue( icon, "pressedCheckmarkColor", Color.WHITE ); + testValue( icon, "pressedIndeterminateBorderColor", Color.WHITE ); + testValue( icon, "pressedIndeterminateBackground", Color.WHITE ); + testValue( icon, "pressedIndeterminateCheckmarkColor", Color.WHITE ); } @Test diff --git a/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyling.java b/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyling.java index d20e49fb..209cad9b 100644 --- a/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyling.java +++ b/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyling.java @@ -1390,6 +1390,8 @@ public class TestFlatStyling icon.applyStyleProperty( "borderWidth", 1.5f ); icon.applyStyleProperty( "selectedBorderWidth", 1.5f ); icon.applyStyleProperty( "disabledSelectedBorderWidth", 1.5f ); + icon.applyStyleProperty( "indeterminateBorderWidth", 1.5f ); + icon.applyStyleProperty( "disabledIndeterminateBorderWidth", 1.5f ); icon.applyStyleProperty( "arc", 5 ); // enabled @@ -1398,6 +1400,9 @@ public class TestFlatStyling icon.applyStyleProperty( "selectedBorderColor", Color.WHITE ); icon.applyStyleProperty( "selectedBackground", Color.WHITE ); icon.applyStyleProperty( "checkmarkColor", Color.WHITE ); + icon.applyStyleProperty( "indeterminateBorderColor", Color.WHITE ); + icon.applyStyleProperty( "indeterminateBackground", Color.WHITE ); + icon.applyStyleProperty( "indeterminateCheckmarkColor", Color.WHITE ); // disabled icon.applyStyleProperty( "disabledBorderColor", Color.WHITE ); @@ -1405,6 +1410,9 @@ public class TestFlatStyling icon.applyStyleProperty( "disabledSelectedBorderColor", Color.WHITE ); icon.applyStyleProperty( "disabledSelectedBackground", Color.WHITE ); icon.applyStyleProperty( "disabledCheckmarkColor", Color.WHITE ); + icon.applyStyleProperty( "disabledIndeterminateBorderColor", Color.WHITE ); + icon.applyStyleProperty( "disabledIndeterminateBackground", Color.WHITE ); + icon.applyStyleProperty( "disabledIndeterminateCheckmarkColor", Color.WHITE ); // focused icon.applyStyleProperty( "focusedBorderColor", Color.WHITE ); @@ -1412,6 +1420,9 @@ public class TestFlatStyling icon.applyStyleProperty( "focusedSelectedBorderColor", Color.WHITE ); icon.applyStyleProperty( "focusedSelectedBackground", Color.WHITE ); icon.applyStyleProperty( "focusedCheckmarkColor", Color.WHITE ); + icon.applyStyleProperty( "focusedIndeterminateBorderColor", Color.WHITE ); + icon.applyStyleProperty( "focusedIndeterminateBackground", Color.WHITE ); + icon.applyStyleProperty( "focusedIndeterminateCheckmarkColor", Color.WHITE ); // hover icon.applyStyleProperty( "hoverBorderColor", Color.WHITE ); @@ -1419,6 +1430,9 @@ public class TestFlatStyling icon.applyStyleProperty( "hoverSelectedBorderColor", Color.WHITE ); icon.applyStyleProperty( "hoverSelectedBackground", Color.WHITE ); icon.applyStyleProperty( "hoverCheckmarkColor", Color.WHITE ); + icon.applyStyleProperty( "hoverIndeterminateBorderColor", Color.WHITE ); + icon.applyStyleProperty( "hoverIndeterminateBackground", Color.WHITE ); + icon.applyStyleProperty( "hoverIndeterminateCheckmarkColor", Color.WHITE ); // pressed icon.applyStyleProperty( "pressedBorderColor", Color.WHITE ); @@ -1426,6 +1440,9 @@ public class TestFlatStyling icon.applyStyleProperty( "pressedSelectedBorderColor", Color.WHITE ); icon.applyStyleProperty( "pressedSelectedBackground", Color.WHITE ); icon.applyStyleProperty( "pressedCheckmarkColor", Color.WHITE ); + icon.applyStyleProperty( "pressedIndeterminateBorderColor", Color.WHITE ); + icon.applyStyleProperty( "pressedIndeterminateBackground", Color.WHITE ); + icon.applyStyleProperty( "pressedIndeterminateCheckmarkColor", Color.WHITE ); } @Test diff --git a/flatlaf-extras/src/main/resources/com/formdev/flatlaf/extras/resources/DerivedColorKeys.properties b/flatlaf-extras/src/main/resources/com/formdev/flatlaf/extras/resources/DerivedColorKeys.properties index c7e0eccf..c1231de4 100644 --- a/flatlaf-extras/src/main/resources/com/formdev/flatlaf/extras/resources/DerivedColorKeys.properties +++ b/flatlaf-extras/src/main/resources/com/formdev/flatlaf/extras/resources/DerivedColorKeys.properties @@ -62,6 +62,9 @@ CheckBox.icon.pressedBackground = CheckBox.icon.background CheckBox.icon.focusedSelectedBackground = CheckBox.icon.selectedBackground CheckBox.icon.hoverSelectedBackground = CheckBox.icon.selectedBackground CheckBox.icon.pressedSelectedBackground = CheckBox.icon.selectedBackground +CheckBox.icon.focusedIndeterminateBackground = CheckBox.icon.indeterminateBackground +CheckBox.icon.hoverIndeterminateBackground = CheckBox.icon.indeterminateBackground +CheckBox.icon.pressedIndeterminateBackground = CheckBox.icon.indeterminateBackground CheckBox.icon[filled].disabledBackground = CheckBox.icon[filled].background CheckBox.icon[filled].focusedBackground = CheckBox.icon[filled].background @@ -70,7 +73,9 @@ CheckBox.icon[filled].pressedBackground = CheckBox.icon[filled].background CheckBox.icon[filled].focusedSelectedBackground = CheckBox.icon[filled].selectedBackground CheckBox.icon[filled].hoverSelectedBackground = CheckBox.icon[filled].selectedBackground CheckBox.icon[filled].pressedSelectedBackground = CheckBox.icon[filled].selectedBackground - +CheckBox.icon[filled].focusedIndeterminateBackground = CheckBox.icon[filled].indeterminateBackground +CheckBox.icon[filled].hoverIndeterminateBackground = CheckBox.icon[filled].indeterminateBackground +CheckBox.icon[filled].pressedIndeterminateBackground = CheckBox.icon[filled].indeterminateBackground #---- CheckBoxMenuItem ---- diff --git a/flatlaf-theme-editor/src/main/java/com/formdev/flatlaf/themeeditor/FlatThemePreviewSwitches.java b/flatlaf-theme-editor/src/main/java/com/formdev/flatlaf/themeeditor/FlatThemePreviewSwitches.java index 6c840b76..76edcb71 100644 --- a/flatlaf-theme-editor/src/main/java/com/formdev/flatlaf/themeeditor/FlatThemePreviewSwitches.java +++ b/flatlaf-theme-editor/src/main/java/com/formdev/flatlaf/themeeditor/FlatThemePreviewSwitches.java @@ -672,7 +672,7 @@ class FlatThemePreviewSwitches } @Override public boolean isSelected() { - return isStateSelected(); + return isStateSelected() || isStateIndeterminate(); } } ); diff --git a/flatlaf-theme-editor/src/main/resources/com/formdev/flatlaf/themeeditor/FlatLafUIKeys.txt b/flatlaf-theme-editor/src/main/resources/com/formdev/flatlaf/themeeditor/FlatLafUIKeys.txt index 7f3ec73a..4b765662 100644 --- a/flatlaf-theme-editor/src/main/resources/com/formdev/flatlaf/themeeditor/FlatLafUIKeys.txt +++ b/flatlaf-theme-editor/src/main/resources/com/formdev/flatlaf/themeeditor/FlatLafUIKeys.txt @@ -98,6 +98,10 @@ CheckBox.icon.checkmarkColor CheckBox.icon.disabledBackground CheckBox.icon.disabledBorderColor CheckBox.icon.disabledCheckmarkColor +CheckBox.icon.disabledIndeterminateBackground +CheckBox.icon.disabledIndeterminateBorderColor +CheckBox.icon.disabledIndeterminateBorderWidth +CheckBox.icon.disabledIndeterminateCheckmarkColor CheckBox.icon.disabledSelectedBackground CheckBox.icon.disabledSelectedBorderColor CheckBox.icon.disabledSelectedBorderWidth @@ -106,16 +110,29 @@ CheckBox.icon.focusWidth CheckBox.icon.focusedBackground CheckBox.icon.focusedBorderColor CheckBox.icon.focusedCheckmarkColor +CheckBox.icon.focusedIndeterminateBackground +CheckBox.icon.focusedIndeterminateBorderColor +CheckBox.icon.focusedIndeterminateCheckmarkColor CheckBox.icon.focusedSelectedBackground CheckBox.icon.focusedSelectedBorderColor CheckBox.icon.hoverBackground CheckBox.icon.hoverBorderColor CheckBox.icon.hoverCheckmarkColor +CheckBox.icon.hoverIndeterminateBackground +CheckBox.icon.hoverIndeterminateBorderColor +CheckBox.icon.hoverIndeterminateCheckmarkColor CheckBox.icon.hoverSelectedBackground CheckBox.icon.hoverSelectedBorderColor +CheckBox.icon.indeterminateBackground +CheckBox.icon.indeterminateBorderColor +CheckBox.icon.indeterminateBorderWidth +CheckBox.icon.indeterminateCheckmarkColor CheckBox.icon.pressedBackground CheckBox.icon.pressedBorderColor CheckBox.icon.pressedCheckmarkColor +CheckBox.icon.pressedIndeterminateBackground +CheckBox.icon.pressedIndeterminateBorderColor +CheckBox.icon.pressedIndeterminateCheckmarkColor CheckBox.icon.pressedSelectedBackground CheckBox.icon.pressedSelectedBorderColor CheckBox.icon.selectedBackground @@ -130,6 +147,10 @@ CheckBox.icon[filled].checkmarkColor CheckBox.icon[filled].disabledBackground CheckBox.icon[filled].disabledBorderColor CheckBox.icon[filled].disabledCheckmarkColor +CheckBox.icon[filled].disabledIndeterminateBackground +CheckBox.icon[filled].disabledIndeterminateBorderColor +CheckBox.icon[filled].disabledIndeterminateBorderWidth +CheckBox.icon[filled].disabledIndeterminateCheckmarkColor CheckBox.icon[filled].disabledSelectedBackground CheckBox.icon[filled].disabledSelectedBorderColor CheckBox.icon[filled].disabledSelectedBorderWidth @@ -137,16 +158,29 @@ CheckBox.icon[filled].focusWidth CheckBox.icon[filled].focusedBackground CheckBox.icon[filled].focusedBorderColor CheckBox.icon[filled].focusedCheckmarkColor +CheckBox.icon[filled].focusedIndeterminateBackground +CheckBox.icon[filled].focusedIndeterminateBorderColor +CheckBox.icon[filled].focusedIndeterminateCheckmarkColor CheckBox.icon[filled].focusedSelectedBackground CheckBox.icon[filled].focusedSelectedBorderColor CheckBox.icon[filled].hoverBackground CheckBox.icon[filled].hoverBorderColor CheckBox.icon[filled].hoverCheckmarkColor +CheckBox.icon[filled].hoverIndeterminateBackground +CheckBox.icon[filled].hoverIndeterminateBorderColor +CheckBox.icon[filled].hoverIndeterminateCheckmarkColor CheckBox.icon[filled].hoverSelectedBackground CheckBox.icon[filled].hoverSelectedBorderColor +CheckBox.icon[filled].indeterminateBackground +CheckBox.icon[filled].indeterminateBorderColor +CheckBox.icon[filled].indeterminateBorderWidth +CheckBox.icon[filled].indeterminateCheckmarkColor CheckBox.icon[filled].pressedBackground CheckBox.icon[filled].pressedBorderColor CheckBox.icon[filled].pressedCheckmarkColor +CheckBox.icon[filled].pressedIndeterminateBackground +CheckBox.icon[filled].pressedIndeterminateBorderColor +CheckBox.icon[filled].pressedIndeterminateCheckmarkColor CheckBox.icon[filled].pressedSelectedBackground CheckBox.icon[filled].pressedSelectedBorderColor CheckBox.icon[filled].selectedBackground