diff --git a/CHANGELOG.md b/CHANGELOG.md index 34d73660..5827b33b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ FlatLaf Change Log and "One Dark" themes. - TabbedPane: Support hiding tab area if it contains only one tab. (set client property `JTabbedPane.hideTabAreaWithOneTab` to `true`) +- 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 b49d2df1..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,8 +247,11 @@ public class FlatMenuItemRenderer g.setColor( Color.orange ); g.drawRect( arrowRect.x, arrowRect.y, arrowRect.width - 1, arrowRect.height - 1 ); debug*/ - paintBackground( g, selectionBackground ); - 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 ) ) @@ -257,36 +261,36 @@ debug*/ 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 503e3981..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 @@ -62,6 +62,12 @@ import javax.swing.plaf.basic.BasicMenuUI; * @uiDefault MenuItem.iconTextGap int * @uiDefault MenuBar.hoverBackground Color * + * + * + * @uiDefault MenuBar.underlineSelectionBackground Color + * @uiDefault MenuBar.underlineSelectionColor Color + * @uiDefault MenuBar.underlineSelectionHeight int + * * @author Karl Tauber */ public class FlatMenuUI @@ -147,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 ) { @@ -155,6 +165,9 @@ public class FlatMenuUI @Override 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() ) @@ -164,5 +177,15 @@ public class FlatMenuUI } else 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-testing/dumps/uidefaults/FlatTestLaf_1.8.0_202.txt b/flatlaf-testing/dumps/uidefaults/FlatTestLaf_1.8.0_202.txt index 142a62b6..a5819331 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 477c8ee9..13b5145f 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 ----