diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d2a186e..eaac11b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ FlatLaf Change Log - Added "Gradianto Nature Green" theme. - Updated "Arc Dark", "Cyan", "Dark purple", "Gradianto", "Gray", "Gruvbox" and "One Dark" themes. +- MenuBar: Support different underline menu selection style UI defaults for + `MenuBar` and `MenuItem`. (PR #217; issue #216) #### Fixed bugs diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuItemRenderer.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuItemRenderer.java index 6c1d6b24..8fe99aee 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuItemRenderer.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuItemRenderer.java @@ -39,6 +39,7 @@ import javax.swing.UIManager; import javax.swing.plaf.basic.BasicHTML; import javax.swing.text.View; import com.formdev.flatlaf.FlatLaf; +import com.formdev.flatlaf.util.DerivedColor; import com.formdev.flatlaf.util.Graphics2DProxy; import com.formdev.flatlaf.util.HiDPIUtils; import com.formdev.flatlaf.util.SystemInfo; @@ -55,7 +56,7 @@ import com.formdev.flatlaf.util.SystemInfo; * @uiDefault MenuItem.underlineSelectionBackground Color * @uiDefault MenuItem.underlineSelectionCheckBackground Color * @uiDefault MenuItem.underlineSelectionColor Color - * @uiDefault MenuItem.underlineSelectionHeight Color + * @uiDefault MenuItem.underlineSelectionHeight int * * @author Karl Tauber */ @@ -246,47 +247,50 @@ public class FlatMenuItemRenderer g.setColor( Color.orange ); g.drawRect( arrowRect.x, arrowRect.y, arrowRect.width - 1, arrowRect.height - 1 ); debug*/ - paintBackground( g, selectionBackground, underlineSelectionColor ); - paintIcon( g, iconRect, getIconForPainting() ); + boolean underlineSelection = isUnderlineSelection(); + paintBackground( g, underlineSelection ? underlineSelectionBackground : selectionBackground ); + if( underlineSelection && isArmedOrSelected( menuItem ) ) + paintUnderlineSelection( g, underlineSelectionColor, underlineSelectionHeight ); + paintIcon( g, iconRect, getIconForPainting(), underlineSelection ? underlineSelectionCheckBackground : checkBackground ); paintText( g, textRect, menuItem.getText(), selectionForeground, disabledForeground ); paintAccelerator( g, accelRect, getAcceleratorText(), acceleratorForeground, acceleratorSelectionForeground, disabledForeground ); if( !isTopLevelMenu( menuItem ) ) paintArrowIcon( g, arrowRect, arrowIcon ); } - protected void paintBackground( Graphics g, Color selectionBackground, Color underlineSelectionColor ) { + protected void paintBackground( Graphics g, Color selectionBackground ) { boolean armedOrSelected = isArmedOrSelected( menuItem ); if( menuItem.isOpaque() || armedOrSelected ) { - int width = menuItem.getWidth(); - int height = menuItem.getHeight(); - // paint background g.setColor( armedOrSelected - ? (isUnderlineSelection() - ? deriveBackground( underlineSelectionBackground ) - : selectionBackground) + ? deriveBackground( selectionBackground ) : menuItem.getBackground() ); - g.fillRect( 0, 0, width, height ); + g.fillRect( 0, 0, menuItem.getWidth(), menuItem.getHeight() ); + } + } - // paint underline - if( armedOrSelected && isUnderlineSelection() ) { - int underlineHeight = scale( underlineSelectionHeight ); - g.setColor( underlineSelectionColor ); - if( isTopLevelMenu( menuItem ) ) { - // paint underline at bottom - g.fillRect( 0, height - underlineHeight, width, underlineHeight ); - } else if( menuItem.getComponentOrientation().isLeftToRight() ) { - // paint underline at left side - g.fillRect( 0, 0, underlineHeight, height ); - } else { - // paint underline at right side - g.fillRect( width - underlineHeight, 0, underlineHeight, height ); - } - } + protected void paintUnderlineSelection( Graphics g, Color underlineSelectionColor, int underlineSelectionHeight ) { + int width = menuItem.getWidth(); + int height = menuItem.getHeight(); + + int underlineHeight = scale( underlineSelectionHeight ); + g.setColor( underlineSelectionColor ); + if( isTopLevelMenu( menuItem ) ) { + // paint underline at bottom + g.fillRect( 0, height - underlineHeight, width, underlineHeight ); + } else if( menuItem.getComponentOrientation().isLeftToRight() ) { + // paint underline at left side + g.fillRect( 0, 0, underlineHeight, height ); + } else { + // paint underline at right side + g.fillRect( width - underlineHeight, 0, underlineHeight, height ); } } protected Color deriveBackground( Color background ) { + if( !(background instanceof DerivedColor) ) + return background; + Color baseColor = menuItem.isOpaque() ? menuItem.getBackground() : FlatUIUtils.getParentBackground( menuItem ); @@ -294,12 +298,12 @@ debug*/ return FlatUIUtils.deriveColor( background, baseColor ); } - protected void paintIcon( Graphics g, Rectangle iconRect, Icon icon ) { + protected void paintIcon( Graphics g, Rectangle iconRect, Icon icon, Color checkBackground ) { // if checkbox/radiobutton menu item is selected and also has a custom icon, // then use filled icon background to indicate selection (instead of using checkIcon) if( menuItem.isSelected() && checkIcon != null && icon != checkIcon ) { Rectangle r = FlatUIUtils.addInsets( iconRect, scale( checkMargins ) ); - g.setColor( deriveBackground( isUnderlineSelection() ? underlineSelectionCheckBackground : checkBackground ) ); + g.setColor( deriveBackground( checkBackground ) ); g.fillRect( r.x, r.y, r.width, r.height ); } diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuUI.java index 2edfc3b2..8f80c6c2 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuUI.java @@ -60,16 +60,19 @@ import javax.swing.plaf.basic.BasicMenuUI; * * * @uiDefault MenuItem.iconTextGap int - * @uiDefault MenuBar.hoverBackground + * @uiDefault MenuBar.hoverBackground Color + * + * + * + * @uiDefault MenuBar.underlineSelectionBackground Color * @uiDefault MenuBar.underlineSelectionColor Color + * @uiDefault MenuBar.underlineSelectionHeight int * * @author Karl Tauber */ public class FlatMenuUI extends BasicMenuUI { - protected final Color menuBarUnderlineSelectionColor = UIManager.getColor( "MenuBar.underlineSelectionColor" ); - private Color hoverBackground; private FlatMenuItemRenderer renderer; @@ -150,6 +153,10 @@ public class FlatMenuUI protected class FlatMenuRenderer extends FlatMenuItemRenderer { + protected final Color menuBarUnderlineSelectionBackground = FlatUIUtils.getUIColor( "MenuBar.underlineSelectionBackground", underlineSelectionBackground ); + protected final Color menuBarUnderlineSelectionColor = FlatUIUtils.getUIColor( "MenuBar.underlineSelectionColor", underlineSelectionColor ); + protected final int menuBarUnderlineSelectionHeight = FlatUIUtils.getUIInt( "MenuBar.underlineSelectionHeight", underlineSelectionHeight ); + protected FlatMenuRenderer( JMenuItem menuItem, Icon checkIcon, Icon arrowIcon, Font acceleratorFont, String acceleratorDelimiter ) { @@ -157,7 +164,10 @@ public class FlatMenuUI } @Override - protected void paintBackground( Graphics g, Color selectionBackground, Color menuItemUnderlineSelectionColor ) { + protected void paintBackground( Graphics g, Color selectionBackground ) { + if( isUnderlineSelection() && ((JMenu)menuItem).isTopLevelMenu() ) + selectionBackground = menuBarUnderlineSelectionBackground; + ButtonModel model = menuItem.getModel(); if( model.isRollover() && !model.isArmed() && !model.isSelected() && model.isEnabled() && ((JMenu)menuItem).isTopLevelMenu() ) @@ -165,7 +175,17 @@ public class FlatMenuUI g.setColor( deriveBackground( hoverBackground ) ); g.fillRect( 0, 0, menuItem.getWidth(), menuItem.getHeight() ); } else - super.paintBackground( g, selectionBackground, ((JMenu)menuItem).isTopLevelMenu() ? menuBarUnderlineSelectionColor : menuItemUnderlineSelectionColor ); + super.paintBackground( g, selectionBackground ); + } + + @Override + protected void paintUnderlineSelection( Graphics g, Color underlineSelectionColor, int underlineSelectionHeight ) { + if( ((JMenu)menuItem).isTopLevelMenu() ) { + underlineSelectionColor = menuBarUnderlineSelectionColor; + underlineSelectionHeight = menuBarUnderlineSelectionHeight; + } + + super.paintUnderlineSelection( g, underlineSelectionColor, underlineSelectionHeight ); } } } diff --git a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties index ac52502d..0b94527b 100644 --- a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties +++ b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties @@ -337,7 +337,6 @@ MenuBar.border=com.formdev.flatlaf.ui.FlatMenuBarBorder MenuBar.background=@menuBackground MenuBar.hoverBackground=@menuHoverBackground MenuBar.itemMargins=3,8,3,8 -MenuBar.underlineSelectionColor=$TabbedPane.underlineColor #---- MenuItem ---- diff --git a/flatlaf-testing/dumps/uidefaults/FlatTestLaf_1.8.0_202.txt b/flatlaf-testing/dumps/uidefaults/FlatTestLaf_1.8.0_202.txt index 5e1b71d9..1be80b34 100644 --- a/flatlaf-testing/dumps/uidefaults/FlatTestLaf_1.8.0_202.txt +++ b/flatlaf-testing/dumps/uidefaults/FlatTestLaf_1.8.0_202.txt @@ -518,6 +518,9 @@ MenuBar.highlight #ffffff javax.swing.plaf.ColorUIResource [UI] MenuBar.hoverBackground #ffdddd javax.swing.plaf.ColorUIResource [UI] MenuBar.itemMargins 3,8,3,8 javax.swing.plaf.InsetsUIResource [UI] MenuBar.shadow #a0a0a0 javax.swing.plaf.ColorUIResource [UI] +MenuBar.underlineSelectionBackground #00ff00 javax.swing.plaf.ColorUIResource [UI] +MenuBar.underlineSelectionColor #ff0000 javax.swing.plaf.ColorUIResource [UI] +MenuBar.underlineSelectionHeight 5 MenuBar.windowBindings length=2 [Ljava.lang.Object; [0] F10 [1] takeFocus 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 b4e350ba..2f104103 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 @@ -192,6 +192,9 @@ Menu.icon.disabledArrowColor=#ABABAB MenuBar.borderColor=#44f MenuBar.hoverBackground=#fdd +MenuBar.underlineSelectionBackground=#0f0 +MenuBar.underlineSelectionColor=#f00 +MenuBar.underlineSelectionHeight=5 #---- MenuItemCheckBox ----