From e5fcc5980522b34703bcdb673834bc8d98a77ff7 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Sat, 30 Nov 2019 19:14:37 +0100 Subject: [PATCH] Button: optionally support shadows for improved compatibility with IntelliJ platform themes (e.g. for Material Design Dark theme) --- CHANGELOG.md | 6 ++--- .../com/formdev/flatlaf/IntelliJTheme.java | 4 +++ .../com/formdev/flatlaf/ui/FlatButtonUI.java | 27 ++++++++++++++++++- 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 20f4ad5d..f958a1b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,9 +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). +- Button: Optionally support gradient borders, gradient backgrounds and shadows + for improved compatibility with IntelliJ platform themes (e.g. for Vuesion, + Spacegray and Material Design Dark 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 8b58f740..7a1717c0 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/IntelliJTheme.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/IntelliJTheme.java @@ -128,6 +128,10 @@ public class IntelliJTheme defaults.put( "Component.isIntelliJTheme", true ); + // enable button shadows + defaults.put( "Button.paintShadow", true ); + defaults.put( "Button.shadowWidth", dark ? 2 : 1 ); + loadNamedColors( defaults ); // convert Json "ui" structure to UI defaults 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 7f684a80..c42075d7 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 @@ -27,6 +27,7 @@ import java.awt.GradientPaint; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Rectangle; +import java.awt.geom.RoundRectangle2D; import javax.swing.AbstractButton; import javax.swing.ButtonModel; import javax.swing.Icon; @@ -40,6 +41,7 @@ import javax.swing.plaf.ComponentUI; import javax.swing.plaf.UIResource; import javax.swing.plaf.basic.BasicButtonUI; import com.formdev.flatlaf.FlatLaf; +import com.formdev.flatlaf.util.UIScale; /** * Provides the Flat LaF UI delegate for {@link javax.swing.JButton}. @@ -73,6 +75,10 @@ import com.formdev.flatlaf.FlatLaf; * @uiDefault Button.default.hoverBackground Color optional * @uiDefault Button.default.pressedBackground Color optional * @uiDefault Button.default.boldText boolean + * @uiDefault Button.paintShadow boolean default is false + * @uiDefault Button.shadowWidth int default is 2 + * @uiDefault Button.shadowColor Color optional + * @uiDefault Button.default.shadowColor Color optional * @uiDefault Button.toolbar.hoverBackground Color * @uiDefault Button.toolbar.pressedBackground Color * @@ -101,6 +107,10 @@ public class FlatButtonUI protected Color defaultPressedBackground; protected boolean defaultBoldText; + protected int shadowWidth; + protected Color shadowColor; + protected Color defaultShadowColor; + protected Color toolbarHoverBackground; protected Color toolbarPressedBackground; @@ -135,6 +145,12 @@ public class FlatButtonUI pressedBackground = UIManager.getColor( prefix + "pressedBackground" ); disabledText = UIManager.getColor( prefix + "disabledText" ); + if( UIManager.getBoolean( "Button.paintShadow" ) ) { + shadowWidth = FlatUIUtils.getUIInt( "Button.shadowWidth", 2 ); + shadowColor = UIManager.getColor( "Button.shadowColor" ); + defaultShadowColor = UIManager.getColor( "Button.default.shadowColor" ); + } + defaultBackground = FlatUIUtils.getUIColor( "Button.default.startBackground", "Button.default.background" ); defaultEndBackground = UIManager.getColor( "Button.default.endBackground" ); defaultForeground = UIManager.getColor( "Button.default.foreground" ); @@ -219,9 +235,18 @@ public class FlatButtonUI 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 ); + + // paint shadow + Color shadowColor = def ? defaultShadowColor : this.shadowColor; + if( shadowColor != null && shadowWidth > 0 && focusWidth > 0 && !c.hasFocus() && c.isEnabled() ) { + g2.setColor( shadowColor ); + g2.fill( new RoundRectangle2D.Float( focusWidth, focusWidth + UIScale.scale( (float) shadowWidth ), + c.getWidth() - focusWidth * 2, c.getHeight() - focusWidth * 2, arc, arc ) ); + } + + // paint background Color startBg = def ? defaultBackground : startBackground; Color endBg = def ? defaultEndBackground : endBackground; - if( background == startBg && endBg != null && !startBg.equals( endBg ) ) g2.setPaint( new GradientPaint( 0, 0, startBg, 0, c.getHeight(), endBg ) ); else