From de82dac87323d9dad72484dd76265b059de7cc30 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Sat, 30 Nov 2019 17:58:40 +0100 Subject: [PATCH] Button: optionally support gradient border and gradient background for improved compatibility with IntelliJ platform themes (e.g. Vuesion and Spacegray themes) --- CHANGELOG.md | 3 +++ .../com/formdev/flatlaf/IntelliJTheme.java | 11 -------- .../com/formdev/flatlaf/ui/FlatBorder.java | 5 ++-- .../formdev/flatlaf/ui/FlatButtonBorder.java | 24 ++++++++++++++--- .../com/formdev/flatlaf/ui/FlatButtonUI.java | 27 +++++++++++++++++-- .../flatlaf/ui/FlatToggleButtonUI.java | 2 ++ .../flatlaf/testing/FlatTestLaf.properties | 12 ++++++--- .../testing/swingx/FlatTestLaf.properties | 5 ++++ 8 files changed, 66 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d6d0e11..20f4ad5d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ FlatLaf Change Log ## Unreleased - `FlatLaf.isNativeLookAndFeel()` now returns `false`. +- Button: Optionally support gradient border and gradient background for + improved compatibility with IntelliJ platform themes (e.g. Vuesion and + Spacegray themes). ## 0.20 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 10702c81..8b58f740 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/IntelliJTheme.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/IntelliJTheme.java @@ -380,17 +380,6 @@ public class IntelliJTheme private static Set noWildcardReplace = new HashSet<>(); static { - // Button - // IDEA buttons support gradient for background and border, but FlatLaf does not - uiKeyMapping.put( "Button.startBackground", "Button.background" ); - uiKeyMapping.put( "Button.startBorderColor", "Button.borderColor" ); - uiKeyMapping.put( "Button.default.startBackground", "Button.default.background" ); - uiKeyMapping.put( "Button.default.startBorderColor", "Button.default.borderColor" ); - uiKeyMapping.put( "Button.endBackground", "" ); // ignore - uiKeyMapping.put( "Button.endBorderColor", "" ); // ignore - uiKeyMapping.put( "Button.default.endBackground", "" ); // ignore - uiKeyMapping.put( "Button.default.endBorderColor", "" ); // ignore - // ComboBox uiKeyMapping.put( "ComboBox.background", "" ); // ignore uiKeyMapping.put( "ComboBox.nonEditableBackground", "ComboBox.background" ); diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatBorder.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatBorder.java index 9a6b39ff..482d928a 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatBorder.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatBorder.java @@ -23,6 +23,7 @@ import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Insets; import java.awt.KeyboardFocusManager; +import java.awt.Paint; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JScrollPane; @@ -82,7 +83,7 @@ public class FlatBorder getLineWidth() + scale( (float) innerFocusWidth ), arc ); } - g2.setColor( getBorderColor( c ) ); + g2.setPaint( getBorderColor( c ) ); FlatUIUtils.drawRoundRectangle( g2, x, y, width, height, focusWidth, borderWidth, arc ); } finally { g2.dispose(); @@ -93,7 +94,7 @@ public class FlatBorder return focusColor; } - protected Color getBorderColor( Component c ) { + protected Paint getBorderColor( Component c ) { boolean enabled = c.isEnabled() && (!(c instanceof JTextComponent) || ((JTextComponent)c).isEditable()); return enabled ? (isFocused( c ) ? focusedBorderColor : borderColor) diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatButtonBorder.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatButtonBorder.java index 487f8912..145565ef 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatButtonBorder.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatButtonBorder.java @@ -19,8 +19,10 @@ package com.formdev.flatlaf.ui; import static com.formdev.flatlaf.util.UIScale.scale; import java.awt.Color; import java.awt.Component; +import java.awt.GradientPaint; import java.awt.Graphics; import java.awt.Insets; +import java.awt.Paint; import javax.swing.JButton; import javax.swing.UIManager; import javax.swing.plaf.UIResource; @@ -29,10 +31,14 @@ import javax.swing.plaf.UIResource; * Border for {@link javax.swing.JButton}. * * @uiDefault Button.borderColor Color + * @uiDefault Button.startBorderColor Color optional; if set, a gradient paint is used and Button.borderColor is ignored + * @uiDefault Button.endBorderColor Color optional; if set, a gradient paint is used * @uiDefault Button.disabledBorderColor Color * @uiDefault Button.focusedBorderColor Color * @uiDefault Button.hoverBorderColor Color optional * @uiDefault Button.default.borderColor Color + * @uiDefault Button.default.startBorderColor Color optional; if set, a gradient paint is used and Button.default.borderColor is ignored + * @uiDefault Button.default.endBorderColor Color optional; if set, a gradient paint is used * @uiDefault Button.default.hoverBorderColor Color optional * @uiDefault Button.default.focusedBorderColor Color * @uiDefault Button.default.focusColor Color @@ -44,11 +50,13 @@ import javax.swing.plaf.UIResource; public class FlatButtonBorder extends FlatBorder { - protected final Color borderColor = UIManager.getColor( "Button.borderColor" ); + protected final Color borderColor = FlatUIUtils.getUIColor( "Button.startBorderColor", "Button.borderColor" ); + protected final Color endBorderColor = UIManager.getColor( "Button.endBorderColor" ); protected final Color disabledBorderColor = UIManager.getColor( "Button.disabledBorderColor" ); protected final Color focusedBorderColor = UIManager.getColor( "Button.focusedBorderColor" ); protected final Color hoverBorderColor = UIManager.getColor( "Button.hoverBorderColor" ); - protected final Color defaultBorderColor = UIManager.getColor( "Button.default.borderColor" ); + protected final Color defaultBorderColor = FlatUIUtils.getUIColor( "Button.default.startBorderColor", "Button.default.borderColor" ); + protected final Color defaultEndBorderColor = UIManager.getColor( "Button.default.endBorderColor" ); protected final Color defaultHoverBorderColor = UIManager.getColor( "Button.default.hoverBorderColor" ); protected final Color defaultFocusedBorderColor = UIManager.getColor( "Button.default.focusedBorderColor" ); protected final Color defaultFocusColor = UIManager.getColor( "Button.default.focusColor" ); @@ -67,14 +75,22 @@ public class FlatButtonBorder } @Override - protected Color getBorderColor( Component c ) { + protected Paint getBorderColor( Component c ) { boolean def = FlatButtonUI.isDefaultButton( c ); - return FlatButtonUI.buttonStateColor( c, + Paint color = FlatButtonUI.buttonStateColor( c, def ? defaultBorderColor : borderColor, disabledBorderColor, def ? defaultFocusedBorderColor : focusedBorderColor, def ? defaultHoverBorderColor : hoverBorderColor, null ); + + // change to gradient paint if start/end colors are specified + Color startBg = def ? defaultBorderColor : borderColor; + Color endBg = def ? defaultEndBorderColor : endBorderColor; + if( color == startBg && endBg != null && !startBg.equals( endBg ) ) + color = new GradientPaint( 0, 0, startBg, 0, c.getHeight(), endBg ); + + return color; } @Override diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatButtonUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatButtonUI.java index 87d5c9e7..7f684a80 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatButtonUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatButtonUI.java @@ -23,6 +23,7 @@ import java.awt.Component; import java.awt.Dimension; import java.awt.Font; import java.awt.FontMetrics; +import java.awt.GradientPaint; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Rectangle; @@ -58,11 +59,15 @@ import com.formdev.flatlaf.FlatLaf; * @uiDefault Button.arc int * @uiDefault Button.minimumWidth int * @uiDefault Button.iconTextGap int + * @uiDefault Button.startBackground Color optional; if set, a gradient paint is used and Button.background is ignored + * @uiDefault Button.endBackground Color optional; if set, a gradient paint is used * @uiDefault Button.focusedBackground Color optional * @uiDefault Button.hoverBackground Color optional * @uiDefault Button.pressedBackground Color optional * @uiDefault Button.disabledText Color * @uiDefault Button.default.background Color + * @uiDefault Button.default.startBackground Color optional; if set, a gradient paint is used and Button.default.background is ignored + * @uiDefault Button.default.endBackground Color optional; if set, a gradient paint is used * @uiDefault Button.default.foreground Color * @uiDefault Button.default.focusedBackground Color optional * @uiDefault Button.default.hoverBackground Color optional @@ -81,12 +86,15 @@ public class FlatButtonUI protected int minimumWidth; protected int iconTextGap; + protected Color startBackground; + protected Color endBackground; protected Color focusedBackground; protected Color hoverBackground; protected Color pressedBackground; protected Color disabledText; protected Color defaultBackground; + protected Color defaultEndBackground; protected Color defaultForeground; protected Color defaultFocusedBackground; protected Color defaultHoverBackground; @@ -120,12 +128,15 @@ public class FlatButtonUI minimumWidth = UIManager.getInt( prefix + "minimumWidth" ); iconTextGap = FlatUIUtils.getUIInt( prefix + "iconTextGap", 4 ); + startBackground = UIManager.getColor( prefix + "startBackground" ); + endBackground = UIManager.getColor( prefix + "endBackground" ); focusedBackground = UIManager.getColor( prefix + "focusedBackground" ); hoverBackground = UIManager.getColor( prefix + "hoverBackground" ); pressedBackground = UIManager.getColor( prefix + "pressedBackground" ); disabledText = UIManager.getColor( prefix + "disabledText" ); - defaultBackground = UIManager.getColor( "Button.default.background" ); + defaultBackground = FlatUIUtils.getUIColor( "Button.default.startBackground", "Button.default.background" ); + defaultEndBackground = UIManager.getColor( "Button.default.endBackground" ); defaultForeground = UIManager.getColor( "Button.default.foreground" ); defaultFocusedBackground = UIManager.getColor( "Button.default.focusedBackground" ); defaultHoverBackground = UIManager.getColor( "Button.default.hoverBackground" ); @@ -140,6 +151,12 @@ public class FlatButtonUI defaults_initialized = true; } + if( startBackground != null ) { + Color bg = b.getBackground(); + if( bg == null || bg instanceof UIResource ) + b.setBackground( startBackground ); + } + LookAndFeel.installProperty( b, "opaque", false ); LookAndFeel.installProperty( b, "iconTextGap", scale( iconTextGap ) ); @@ -201,8 +218,14 @@ public class FlatButtonUI Border border = c.getBorder(); float focusWidth = (border instanceof FlatBorder) ? scale( (float) this.focusWidth ) : 0; float arc = (border instanceof FlatButtonBorder || isToolBarButton( c )) ? scale( (float) this.arc ) : 0; + boolean def = isDefaultButton( c ); + Color startBg = def ? defaultBackground : startBackground; + Color endBg = def ? defaultEndBackground : endBackground; - FlatUIUtils.setColor( g2, background, isDefaultButton(c) ? defaultBackground : c.getBackground() ); + if( background == startBg && endBg != null && !startBg.equals( endBg ) ) + g2.setPaint( new GradientPaint( 0, 0, startBg, 0, c.getHeight(), endBg ) ); + else + FlatUIUtils.setColor( g2, background, def ? defaultBackground : c.getBackground() ); FlatUIUtils.fillRoundRectangle( g2, 0, 0, c.getWidth(), c.getHeight(), focusWidth, arc ); } finally { g2.dispose(); diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatToggleButtonUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatToggleButtonUI.java index a03ada17..827cc056 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatToggleButtonUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatToggleButtonUI.java @@ -41,6 +41,8 @@ import javax.swing.plaf.ComponentUI; * @uiDefault ToggleButton.arc int * @uiDefault ToggleButton.minimumWidth int * @uiDefault ToggleButton.iconTextGap int + * @uiDefault ToggleButton.startBackground Color optional; if set, a gradient paint is used and ToggleButton.background is ignored + * @uiDefault ToggleButton.endBackground Color optional; if set, a gradient paint is used * @uiDefault ToggleButton.pressedBackground Color * @uiDefault ToggleButton.disabledText Color * @uiDefault ToggleButton.toolbar.hoverBackground Color diff --git a/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/FlatTestLaf.properties b/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/FlatTestLaf.properties index 3fdc53ea..d9141cd8 100644 --- a/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/FlatTestLaf.properties +++ b/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/FlatTestLaf.properties @@ -47,22 +47,26 @@ #---- Button ---- -Button.background=#ffffff +Button.startBackground=#fff +Button.endBackground=#bbb Button.focusedBackground=#00ffff Button.hoverBackground=#ffff00 Button.pressedBackground=#FFC800 -Button.borderColor=#0000ff +Button.startBorderColor=#00f +Button.endBorderColor=#f00 Button.disabledBorderColor=#000088 Button.focusedBorderColor=#466d94 Button.hoverBorderColor=#ff0000 -Button.default.background=#dddddd +Button.default.startBackground=#ddd +Button.default.endBackground=#888 Button.default.foreground=#880000 Button.default.focusedBackground=#00ffff Button.default.hoverBackground=#ffff00 Button.default.pressedBackground=#FFC800 -Button.default.borderColor=#ff0000 +Button.default.startBorderColor=#f00 +Button.default.endBorderColor=#00f Button.default.hoverBorderColor=#ff0000 Button.default.focusedBorderColor=#537699 Button.default.focusColor=#ff0000 diff --git a/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/swingx/FlatTestLaf.properties b/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/swingx/FlatTestLaf.properties index 732809bc..26906b8e 100644 --- a/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/swingx/FlatTestLaf.properties +++ b/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/swingx/FlatTestLaf.properties @@ -69,3 +69,8 @@ TaskPane.titleOver=#0000aa TaskPane.specialTitleBackground=#00ffff TaskPane.specialTitleForeground=#444444 TaskPane.specialTitleOver=#dd0000 + + +#---- TitledPanel ---- + +JXTitledPanel.borderColor=@@Button.startBorderColor