diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/IntelliJTheme.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/IntelliJTheme.java index 1ec15ba8..930aa29c 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/IntelliJTheme.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/IntelliJTheme.java @@ -126,6 +126,8 @@ public class IntelliJTheme if( ui == null ) return; + defaults.put( "Component.isIntelliJTheme", true ); + loadNamedColors( defaults ); // convert Json "ui" structure to UI defaults @@ -229,7 +231,7 @@ public class IntelliJTheme // (e.g. set ComboBox.buttonEditableBackground to *.background // because it is mapped from ComboBox.ArrowButton.background) String km = uiKeyInverseMapping.getOrDefault( k, (String) k ); - if( km.endsWith( tail ) ) + if( km.endsWith( tail ) && !noWildcardReplace.contains( k ) ) defaults.put( k, uiValue ); } } @@ -312,6 +314,7 @@ public class IntelliJTheme private static Map uiKeyMapping = new HashMap<>(); private static Map uiKeyInverseMapping = new HashMap<>(); private static Map checkboxKeyMapping = new HashMap<>(); + private static Set noWildcardReplace = new HashSet<>(); static { // ComboBox @@ -336,6 +339,16 @@ public class IntelliJTheme checkboxKeyMapping.put( "Checkbox.Border.Selected", "CheckBox.icon.selectedBorderColor" ); checkboxKeyMapping.put( "Checkbox.Foreground.Selected", "CheckBox.icon.checkmarkColor" ); checkboxKeyMapping.put( "Checkbox.Focus.Thin.Selected", "CheckBox.icon.selectedFocusedBorderColor" ); + + // because FlatLaf uses Button.background and Button.borderColor, + // but Darcula uses Button.startBackground and Button.startBorderColor, + // our default button background and border colors may be replaced by + // wildcard *.background and *.borderColor colors + noWildcardReplace.add( "Button.background" ); + noWildcardReplace.add( "Button.borderColor" ); + noWildcardReplace.add( "Button.default.background" ); + noWildcardReplace.add( "Button.default.borderColor" ); + noWildcardReplace.add( "ToggleButton.background" ); } //---- class ThemeLaf ----------------------------------------------------- diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatComboBoxUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatComboBoxUI.java index 59f5246e..7e1fe752 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatComboBoxUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatComboBoxUI.java @@ -70,6 +70,7 @@ import com.formdev.flatlaf.util.UIScale; * @uiDefault Component.focusWidth int * @uiDefault Component.arc int * @uiDefault Component.arrowType String triangle (default) or chevron + * @uiDefault Component.isIntelliJTheme boolean * @uiDefault Component.borderColor Color * @uiDefault Component.disabledBorderColor Color * @uiDefault ComboBox.editableBackground Color optional; defaults to ComboBox.background @@ -89,6 +90,7 @@ public class FlatComboBoxUI protected int focusWidth; protected int arc; protected String arrowType; + protected boolean isIntelliJTheme; protected Color borderColor; protected Color disabledBorderColor; @@ -140,6 +142,7 @@ public class FlatComboBoxUI focusWidth = UIManager.getInt( "Component.focusWidth" ); arc = UIManager.getInt( "Component.arc" ); arrowType = UIManager.getString( "Component.arrowType" ); + isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" ); borderColor = UIManager.getColor( "Component.borderColor" ); disabledBorderColor = UIManager.getColor( "Component.disabledBorderColor" ); @@ -309,7 +312,7 @@ public class FlatComboBoxUI // paint background g2.setColor( enabled ? (editableBackground != null && comboBox.isEditable() ? editableBackground : c.getBackground()) - : disabledBackground ); + : getDisabledBackground( comboBox ) ); FlatUIUtils.fillRoundRectangle( g2, 0, 0, width, height, focusWidth, arc ); // paint arrow button background @@ -347,7 +350,7 @@ public class FlatComboBoxUI boolean enabled = comboBox.isEnabled(); c.setForeground( enabled ? comboBox.getForeground() : disabledForeground ); - c.setBackground( enabled ? comboBox.getBackground() : disabledBackground ); + c.setBackground( enabled ? comboBox.getBackground() : getDisabledBackground( comboBox ) ); boolean shouldValidate = (c instanceof JPanel); if( padding != null ) @@ -364,10 +367,14 @@ public class FlatComboBoxUI @Override public void paintCurrentValueBackground( Graphics g, Rectangle bounds, boolean hasFocus ) { - g.setColor( comboBox.isEnabled() ? comboBox.getBackground() : disabledBackground ); + g.setColor( comboBox.isEnabled() ? comboBox.getBackground() : getDisabledBackground( comboBox ) ); g.fillRect( bounds.x, bounds.y, bounds.width, bounds.height ); } + private Color getDisabledBackground( JComponent c ) { + return isIntelliJTheme ? FlatUIUtils.getParentBackground( c ) : disabledBackground; + } + @Override protected Dimension getSizeForComponent( Component comp ) { Dimension size = super.getSizeForComponent( comp ); diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatEditorPaneUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatEditorPaneUI.java index 4b7e48a9..75dfde0f 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatEditorPaneUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatEditorPaneUI.java @@ -18,11 +18,14 @@ package com.formdev.flatlaf.ui; import static com.formdev.flatlaf.util.UIScale.scale; import java.awt.Dimension; +import java.awt.Graphics; import javax.swing.JComponent; import javax.swing.JEditorPane; import javax.swing.UIManager; import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.UIResource; import javax.swing.plaf.basic.BasicEditorPaneUI; +import javax.swing.text.JTextComponent; /** * Provides the Flat LaF UI delegate for {@link javax.swing.JEditorPane}. @@ -45,6 +48,7 @@ import javax.swing.plaf.basic.BasicEditorPaneUI; * * * @uiDefault Component.minimumWidth int + * @uiDefault Component.isIntelliJTheme boolean * * @author Karl Tauber */ @@ -52,6 +56,7 @@ public class FlatEditorPaneUI extends BasicEditorPaneUI { protected int minimumWidth; + protected boolean isIntelliJTheme; private Object oldHonorDisplayProperties; @@ -64,6 +69,7 @@ public class FlatEditorPaneUI super.installDefaults(); minimumWidth = UIManager.getInt( "Component.minimumWidth" ); + isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" ); // use component font and foreground for HTML text oldHonorDisplayProperties = getComponent().getClientProperty( JEditorPane.HONOR_DISPLAY_PROPERTIES ); @@ -95,4 +101,17 @@ public class FlatEditorPaneUI size.width = Math.max( size.width, scale( minimumWidth ) - (scale( 1 ) * 2) ); return size; } + + @Override + protected void paintBackground( Graphics g ) { + JTextComponent c = getComponent(); + + // for compatibility with IntelliJ themes + if( isIntelliJTheme && (!c.isEnabled() || !c.isEditable()) && (c.getBackground() instanceof UIResource) ) { + FlatUIUtils.paintParentBackground( g, c ); + return; + } + + super.paintBackground( g ); + } } diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatPasswordFieldUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatPasswordFieldUI.java index 6162e1c0..996899c6 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatPasswordFieldUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatPasswordFieldUI.java @@ -50,6 +50,7 @@ import com.formdev.flatlaf.util.SystemInfo; * * @uiDefault Component.focusWidth int * @uiDefault Component.minimumWidth int + * @uiDefault Component.isIntelliJTheme boolean * * @author Karl Tauber */ @@ -58,6 +59,7 @@ public class FlatPasswordFieldUI { protected int focusWidth; protected int minimumWidth; + protected boolean isIntelliJTheme; private FocusListener focusListener; @@ -75,6 +77,7 @@ public class FlatPasswordFieldUI focusWidth = UIManager.getInt( "Component.focusWidth" ); minimumWidth = UIManager.getInt( "Component.minimumWidth" ); + isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" ); LookAndFeel.installProperty( getComponent(), "opaque", focusWidth == 0 ); @@ -106,7 +109,7 @@ public class FlatPasswordFieldUI @Override protected void paintSafely( Graphics g ) { - FlatTextFieldUI.paintBackground( g, getComponent(), focusWidth ); + FlatTextFieldUI.paintBackground( g, getComponent(), focusWidth, isIntelliJTheme ); super.paintSafely( g ); } diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatSpinnerUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatSpinnerUI.java index 518a5167..86fbe451 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatSpinnerUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatSpinnerUI.java @@ -60,6 +60,7 @@ import javax.swing.plaf.basic.BasicSpinnerUI; * @uiDefault Component.arc int * @uiDefault Component.minimumWidth int * @uiDefault Component.arrowType String triangle (default) or chevron + * @uiDefault Component.isIntelliJTheme boolean * @uiDefault Component.borderColor Color * @uiDefault Component.disabledBorderColor Color * @uiDefault Spinner.disabledBackground Color @@ -81,6 +82,7 @@ public class FlatSpinnerUI protected int arc; protected int minimumWidth; protected String arrowType; + protected boolean isIntelliJTheme; protected Color borderColor; protected Color disabledBorderColor; protected Color disabledBackground; @@ -105,6 +107,7 @@ public class FlatSpinnerUI arc = UIManager.getInt( "Component.arc" ); minimumWidth = UIManager.getInt( "Component.minimumWidth" ); arrowType = UIManager.getString( "Component.arrowType" ); + isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" ); borderColor = UIManager.getColor( "Component.borderColor" ); disabledBorderColor = UIManager.getColor( "Component.disabledBorderColor" ); disabledBackground = UIManager.getColor( "Spinner.disabledBackground" ); @@ -261,7 +264,9 @@ public class FlatSpinnerUI boolean isLeftToRight = spinner.getComponentOrientation().isLeftToRight(); // paint background - g2.setColor( enabled ? c.getBackground() : disabledBackground ); + g2.setColor( enabled + ? c.getBackground() + : (isIntelliJTheme ? FlatUIUtils.getParentBackground( c ) : disabledBackground) ); FlatUIUtils.fillRoundRectangle( g2, 0, 0, width, height, focusWidth, arc ); // paint arrow buttons background diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTextAreaUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTextAreaUI.java index a589d60f..a7d2ffb7 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTextAreaUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTextAreaUI.java @@ -47,6 +47,7 @@ import javax.swing.text.JTextComponent; * * * @uiDefault Component.minimumWidth int + * @uiDefault Component.isIntelliJTheme boolean * @uiDefault TextArea.disabledBackground Color used if not enabled * @uiDefault TextArea.inactiveBackground Color used if not editable * @@ -56,6 +57,7 @@ public class FlatTextAreaUI extends BasicTextAreaUI { protected int minimumWidth; + protected boolean isIntelliJTheme; protected Color disabledBackground; protected Color inactiveBackground; @@ -68,6 +70,7 @@ public class FlatTextAreaUI super.installDefaults(); minimumWidth = UIManager.getInt( "Component.minimumWidth" ); + isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" ); disabledBackground = UIManager.getColor( "TextArea.disabledBackground" ); inactiveBackground = UIManager.getColor( "TextArea.inactiveBackground" ); } @@ -87,9 +90,11 @@ public class FlatTextAreaUI Color background = c.getBackground(); g.setColor( !(background instanceof UIResource) ? background - : (!c.isEnabled() - ? disabledBackground - : (!c.isEditable() ? inactiveBackground : background)) ); + : (isIntelliJTheme && (!c.isEnabled() || !c.isEditable()) + ? FlatUIUtils.getParentBackground( c ) + : (!c.isEnabled() + ? disabledBackground + : (!c.isEditable() ? inactiveBackground : background))) ); g.fillRect( 0, 0, c.getWidth(), c.getHeight() ); } diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTextFieldUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTextFieldUI.java index a5679667..04419ec4 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTextFieldUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTextFieldUI.java @@ -17,6 +17,7 @@ package com.formdev.flatlaf.ui; import static com.formdev.flatlaf.util.UIScale.scale; +import java.awt.Color; import java.awt.Container; import java.awt.Dimension; import java.awt.Graphics; @@ -29,6 +30,7 @@ import javax.swing.JTextField; import javax.swing.LookAndFeel; import javax.swing.UIManager; import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.UIResource; import javax.swing.plaf.basic.BasicTextFieldUI; import javax.swing.text.JTextComponent; @@ -54,6 +56,7 @@ import javax.swing.text.JTextComponent; * * @uiDefault Component.focusWidth int * @uiDefault Component.minimumWidth int + * @uiDefault Component.isIntelliJTheme boolean * * @author Karl Tauber */ @@ -62,6 +65,7 @@ public class FlatTextFieldUI { protected int focusWidth; protected int minimumWidth; + protected boolean isIntelliJTheme; private FocusListener focusListener; @@ -75,6 +79,7 @@ public class FlatTextFieldUI focusWidth = UIManager.getInt( "Component.focusWidth" ); minimumWidth = UIManager.getInt( "Component.minimumWidth" ); + isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" ); LookAndFeel.installProperty( getComponent(), "opaque", focusWidth == 0 ); @@ -106,7 +111,7 @@ public class FlatTextFieldUI @Override protected void paintSafely( Graphics g ) { - paintBackground( g, getComponent(), focusWidth ); + paintBackground( g, getComponent(), focusWidth, isIntelliJTheme ); super.paintSafely( g ); } @@ -115,7 +120,7 @@ public class FlatTextFieldUI // background is painted elsewhere } - static void paintBackground( Graphics g, JTextComponent c, int focusWidth ) { + static void paintBackground( Graphics g, JTextComponent c, int focusWidth, boolean isIntelliJTheme ) { // do not paint background if: // - not opaque and // - border is not a flat border and @@ -135,7 +140,12 @@ public class FlatTextFieldUI float fFocusWidth = (c.getBorder() instanceof FlatBorder) ? scale( (float) focusWidth ) : 0; - g2.setColor( c.getBackground() ); + Color background = c.getBackground(); + g2.setColor( !(background instanceof UIResource) + ? background + : (isIntelliJTheme && (!c.isEnabled() || !c.isEditable()) + ? FlatUIUtils.getParentBackground( c ) + : background) ); FlatUIUtils.fillRoundRectangle( g2, 0, 0, c.getWidth(), c.getHeight(), fFocusWidth, 0 ); } finally { g2.dispose(); diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTextPaneUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTextPaneUI.java index 20366d1d..dc3a196c 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTextPaneUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTextPaneUI.java @@ -18,11 +18,14 @@ package com.formdev.flatlaf.ui; import static com.formdev.flatlaf.util.UIScale.scale; import java.awt.Dimension; +import java.awt.Graphics; import javax.swing.JComponent; import javax.swing.JEditorPane; import javax.swing.UIManager; import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.UIResource; import javax.swing.plaf.basic.BasicTextPaneUI; +import javax.swing.text.JTextComponent; /** * Provides the Flat LaF UI delegate for {@link javax.swing.JTextPane}. @@ -45,6 +48,7 @@ import javax.swing.plaf.basic.BasicTextPaneUI; * * * @uiDefault Component.minimumWidth int + * @uiDefault Component.isIntelliJTheme boolean * * @author Karl Tauber */ @@ -52,6 +56,7 @@ public class FlatTextPaneUI extends BasicTextPaneUI { protected int minimumWidth; + protected boolean isIntelliJTheme; private Object oldHonorDisplayProperties; @@ -64,6 +69,7 @@ public class FlatTextPaneUI super.installDefaults(); minimumWidth = UIManager.getInt( "Component.minimumWidth" ); + isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" ); // use component font and foreground for HTML text oldHonorDisplayProperties = getComponent().getClientProperty( JEditorPane.HONOR_DISPLAY_PROPERTIES ); @@ -95,4 +101,17 @@ public class FlatTextPaneUI size.width = Math.max( size.width, scale( minimumWidth ) - (scale( 1 ) * 2) ); return size; } + + @Override + protected void paintBackground( Graphics g ) { + JTextComponent c = getComponent(); + + // for compatibility with IntelliJ themes + if( isIntelliJTheme && (!c.isEnabled() || !c.isEditable()) && (c.getBackground() instanceof UIResource) ) { + FlatUIUtils.paintParentBackground( g, c ); + return; + } + + super.paintBackground( g ); + } } 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 b8c5f748..933903ad 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 @@ -163,6 +163,16 @@ public class FlatUIUtils } } + /** + * Gets the background color of the first opaque parent. + */ + public static Color getParentBackground( JComponent c ) { + Container parent = findOpaqueParent( c ); + return (parent != null) + ? parent.getBackground() + : UIManager.getColor( "Panel.background" ); // fallback, probably never used + } + /** * Find the first parent that is opaque. */