Styling: support Menu, MenuItem, CheckBoxMenuItem and RadioButtonMenuItem

This commit is contained in:
Karl Tauber
2021-06-21 17:24:45 +02:00
parent 20027c2db7
commit 28fb2e2a08
9 changed files with 435 additions and 46 deletions

View File

@@ -24,6 +24,8 @@ import java.awt.geom.Path2D;
import javax.swing.AbstractButton;
import javax.swing.JMenuItem;
import javax.swing.UIManager;
import com.formdev.flatlaf.ui.FlatStyleSupport;
import com.formdev.flatlaf.ui.FlatStyleSupport.Styleable;
/**
* Icon for {@link javax.swing.JCheckBoxMenuItem}.
@@ -38,14 +40,21 @@ import javax.swing.UIManager;
public class FlatCheckBoxMenuItemIcon
extends FlatAbstractIcon
{
protected final Color checkmarkColor = UIManager.getColor( "MenuItemCheckBox.icon.checkmarkColor" );
protected final Color disabledCheckmarkColor = UIManager.getColor( "MenuItemCheckBox.icon.disabledCheckmarkColor" );
protected final Color selectionForeground = UIManager.getColor( "MenuItem.selectionForeground" );
@Styleable protected Color checkmarkColor = UIManager.getColor( "MenuItemCheckBox.icon.checkmarkColor" );
@Styleable protected Color disabledCheckmarkColor = UIManager.getColor( "MenuItemCheckBox.icon.disabledCheckmarkColor" );
@Styleable protected Color selectionForeground = UIManager.getColor( "MenuItem.selectionForeground" );
public FlatCheckBoxMenuItemIcon() {
super( 15, 15, null );
}
/**
* @since TODO
*/
public Object applyStyleProperty( String key, Object value ) {
return FlatStyleSupport.applyToAnnotatedObject( this, key, value );
}
@Override
protected void paintIcon( Component c, Graphics2D g2 ) {
boolean selected = (c instanceof AbstractButton) && ((AbstractButton)c).isSelected();

View File

@@ -23,7 +23,9 @@ import java.awt.Graphics2D;
import java.awt.geom.Path2D;
import javax.swing.JMenu;
import javax.swing.UIManager;
import com.formdev.flatlaf.ui.FlatStyleSupport;
import com.formdev.flatlaf.ui.FlatUIUtils;
import com.formdev.flatlaf.ui.FlatStyleSupport.Styleable;
/**
* "arrow" icon for {@link javax.swing.JMenu}.
@@ -39,22 +41,29 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
public class FlatMenuArrowIcon
extends FlatAbstractIcon
{
protected final boolean chevron = FlatUIUtils.isChevron( UIManager.getString( "Component.arrowType" ) );
protected final Color arrowColor = UIManager.getColor( "Menu.icon.arrowColor" );
protected final Color disabledArrowColor = UIManager.getColor( "Menu.icon.disabledArrowColor" );
protected final Color selectionForeground = UIManager.getColor( "Menu.selectionForeground" );
@Styleable protected String arrowType = UIManager.getString( "Component.arrowType" );
@Styleable protected Color arrowColor = UIManager.getColor( "Menu.icon.arrowColor" );
@Styleable protected Color disabledArrowColor = UIManager.getColor( "Menu.icon.disabledArrowColor" );
@Styleable protected Color selectionForeground = UIManager.getColor( "Menu.selectionForeground" );
public FlatMenuArrowIcon() {
super( 6, 10, null );
}
/**
* @since TODO
*/
public Object applyStyleProperty( String key, Object value ) {
return FlatStyleSupport.applyToAnnotatedObject( this, key, value );
}
@Override
protected void paintIcon( Component c, Graphics2D g ) {
if( !c.getComponentOrientation().isLeftToRight() )
g.rotate( Math.toRadians( 180 ), width / 2., height / 2. );
g.setColor( getArrowColor( c ) );
if( chevron ) {
if( FlatUIUtils.isChevron( arrowType ) ) {
// chevron arrow
Path2D path = FlatUIUtils.createPath( false, 1,1, 5,5, 1,9 );
g.setStroke( new BasicStroke( 1f ) );

View File

@@ -18,11 +18,14 @@ package com.formdev.flatlaf.ui;
import java.awt.Dimension;
import java.awt.Graphics;
import java.beans.PropertyChangeListener;
import java.util.Map;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.LookAndFeel;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicCheckBoxMenuItemUI;
import com.formdev.flatlaf.ui.FlatStyleSupport.UnknownStyleException;
/**
* Provides the Flat LaF UI delegate for {@link javax.swing.JCheckBoxMenuItem}.
@@ -56,11 +59,19 @@ public class FlatCheckBoxMenuItemUI
extends BasicCheckBoxMenuItemUI
{
private FlatMenuItemRenderer renderer;
private Map<String, Object> oldStyleValues;
public static ComponentUI createUI( JComponent c ) {
return new FlatCheckBoxMenuItemUI();
}
@Override
public void installUI( JComponent c ) {
super.installUI( c );
applyStyle( FlatStyleSupport.getStyle( menuItem ) );
}
@Override
protected void installDefaults() {
super.installDefaults();
@@ -81,6 +92,31 @@ public class FlatCheckBoxMenuItemUI
return new FlatMenuItemRenderer( menuItem, checkIcon, arrowIcon, acceleratorFont, acceleratorDelimiter );
}
@Override
protected PropertyChangeListener createPropertyChangeListener( JComponent c ) {
return FlatStyleSupport.createPropertyChangeListener( c, this::applyStyle, super.createPropertyChangeListener( c ) );
}
/**
* @since TODO
*/
protected void applyStyle( Object style ) {
oldStyleValues = FlatStyleSupport.parseAndApply( oldStyleValues, style, this::applyStyleProperty );
}
/**
* @since TODO
*/
protected Object applyStyleProperty( String key, Object value ) {
try {
return renderer.applyStyleProperty( key, value );
} catch ( UnknownStyleException ex ) {
// ignore
}
return FlatMenuItemUI.applyStyleProperty( this, key, value );
}
@Override
protected Dimension getPreferredMenuItemSize( JComponent c, Icon checkIcon, Icon arrowIcon, int defaultTextIconGap ) {
return renderer.getPreferredMenuItemSize();

View File

@@ -39,6 +39,10 @@ import javax.swing.UIManager;
import javax.swing.plaf.basic.BasicHTML;
import javax.swing.text.View;
import com.formdev.flatlaf.FlatLaf;
import com.formdev.flatlaf.icons.FlatCheckBoxMenuItemIcon;
import com.formdev.flatlaf.icons.FlatMenuArrowIcon;
import com.formdev.flatlaf.ui.FlatStyleSupport.Styleable;
import com.formdev.flatlaf.ui.FlatStyleSupport.UnknownStyleException;
import com.formdev.flatlaf.util.DerivedColor;
import com.formdev.flatlaf.util.Graphics2DProxy;
import com.formdev.flatlaf.util.HiDPIUtils;
@@ -57,33 +61,32 @@ import com.formdev.flatlaf.util.SystemInfo;
* @uiDefault MenuItem.underlineSelectionCheckBackground Color
* @uiDefault MenuItem.underlineSelectionColor Color
* @uiDefault MenuItem.underlineSelectionHeight int
* @uiDefault MenuItem.selectionBackground Color
*
* @author Karl Tauber
*/
public class FlatMenuItemRenderer
{
protected final JMenuItem menuItem;
protected final Icon checkIcon;
protected final Icon arrowIcon;
protected Icon checkIcon;
protected Icon arrowIcon;
protected final Font acceleratorFont;
protected final String acceleratorDelimiter;
protected final int minimumWidth = UIManager.getInt( "MenuItem.minimumWidth" );
protected final Dimension minimumIconSize;
protected final int textAcceleratorGap = FlatUIUtils.getUIInt( "MenuItem.textAcceleratorGap", 28 );
protected final int textNoAcceleratorGap = FlatUIUtils.getUIInt( "MenuItem.textNoAcceleratorGap", 6 );
protected final int acceleratorArrowGap = FlatUIUtils.getUIInt( "MenuItem.acceleratorArrowGap", 2 );
@Styleable protected int minimumWidth = UIManager.getInt( "MenuItem.minimumWidth" );
@Styleable protected Dimension minimumIconSize;
@Styleable protected int textAcceleratorGap = FlatUIUtils.getUIInt( "MenuItem.textAcceleratorGap", 28 );
@Styleable protected int textNoAcceleratorGap = FlatUIUtils.getUIInt( "MenuItem.textNoAcceleratorGap", 6 );
@Styleable protected int acceleratorArrowGap = FlatUIUtils.getUIInt( "MenuItem.acceleratorArrowGap", 2 );
protected final Color checkBackground = UIManager.getColor( "MenuItem.checkBackground" );
protected final Insets checkMargins = UIManager.getInsets( "MenuItem.checkMargins" );
@Styleable protected Color checkBackground = UIManager.getColor( "MenuItem.checkBackground" );
@Styleable protected Insets checkMargins = UIManager.getInsets( "MenuItem.checkMargins" );
protected final Color underlineSelectionBackground = UIManager.getColor( "MenuItem.underlineSelectionBackground" );
protected final Color underlineSelectionCheckBackground = UIManager.getColor( "MenuItem.underlineSelectionCheckBackground" );
protected final Color underlineSelectionColor = UIManager.getColor( "MenuItem.underlineSelectionColor" );
protected final int underlineSelectionHeight = UIManager.getInt( "MenuItem.underlineSelectionHeight" );
@Styleable protected Color underlineSelectionBackground = UIManager.getColor( "MenuItem.underlineSelectionBackground" );
@Styleable protected Color underlineSelectionCheckBackground = UIManager.getColor( "MenuItem.underlineSelectionCheckBackground" );
@Styleable protected Color underlineSelectionColor = UIManager.getColor( "MenuItem.underlineSelectionColor" );
@Styleable protected int underlineSelectionHeight = UIManager.getInt( "MenuItem.underlineSelectionHeight" );
protected final Color selectionBackground = UIManager.getColor( "MenuItem.selectionBackground" );
private boolean iconsShared = true;
protected FlatMenuItemRenderer( JMenuItem menuItem, Icon checkIcon, Icon arrowIcon,
Font acceleratorFont, String acceleratorDelimiter )
@@ -98,6 +101,54 @@ public class FlatMenuItemRenderer
this.minimumIconSize = (minimumIconSize != null) ? minimumIconSize : new Dimension( 16, 16 );
}
/**
* @since TODO
*/
protected Object applyStyleProperty( String key, Object value ) {
// style icon
if( key.startsWith( "icon." ) || key.equals( "selectionForeground" ) ) {
if( iconsShared ) {
if( checkIcon instanceof FlatCheckBoxMenuItemIcon )
checkIcon = FlatStyleSupport.cloneIcon( checkIcon );
if( arrowIcon instanceof FlatMenuArrowIcon )
arrowIcon = FlatStyleSupport.cloneIcon( arrowIcon );
iconsShared = false;
}
if( key.startsWith( "icon." ) ) {
String key2 = key.substring( "icon.".length() );
try {
if( checkIcon instanceof FlatCheckBoxMenuItemIcon )
return ((FlatCheckBoxMenuItemIcon)checkIcon).applyStyleProperty( key2, value );
} catch ( UnknownStyleException ex ) {
// ignore
}
try {
if( arrowIcon instanceof FlatMenuArrowIcon )
return ((FlatMenuArrowIcon)arrowIcon).applyStyleProperty( key2, value );
} catch ( UnknownStyleException ex ) {
// ignore
}
// keys with prefix "icon." are only for icons
throw new UnknownStyleException( key );
} else if( key.equals( "selectionForeground" ) ) {
// special case: same key is used in icons and in menuitem
if( checkIcon instanceof FlatCheckBoxMenuItemIcon )
((FlatCheckBoxMenuItemIcon)checkIcon).applyStyleProperty( key, value );
if( arrowIcon instanceof FlatMenuArrowIcon )
((FlatMenuArrowIcon)arrowIcon).applyStyleProperty( key, value );
// throw exception because the caller should also apply this key
throw new UnknownStyleException( key );
}
}
return FlatStyleSupport.applyToAnnotatedObject( this, key, value );
}
protected Dimension getPreferredMenuItemSize() {
int width = 0;
int height = 0;
@@ -254,7 +305,7 @@ debug*/
paintBackground( g, underlineSelection ? underlineSelectionBackground : selectionBackground );
if( underlineSelection && isArmedOrSelected( menuItem ) )
paintUnderlineSelection( g, underlineSelectionColor, underlineSelectionHeight );
paintIcon( g, iconRect, getIconForPainting(), underlineSelection ? underlineSelectionCheckBackground : checkBackground );
paintIcon( g, iconRect, getIconForPainting(), underlineSelection ? underlineSelectionCheckBackground : checkBackground, selectionBackground );
paintText( g, textRect, menuItem.getText(), selectionForeground, disabledForeground );
paintAccelerator( g, accelRect, getAcceleratorText(), acceleratorForeground, acceleratorSelectionForeground, disabledForeground );
if( !isTopLevelMenu( menuItem ) )
@@ -301,7 +352,7 @@ debug*/
return FlatUIUtils.deriveColor( background, baseColor );
}
protected void paintIcon( Graphics g, Rectangle iconRect, Icon icon, Color checkBackground ) {
protected void paintIcon( Graphics g, Rectangle iconRect, Icon icon, Color checkBackground, Color selectionBackground ) {
// 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 ) {

View File

@@ -18,11 +18,14 @@ package com.formdev.flatlaf.ui;
import java.awt.Dimension;
import java.awt.Graphics;
import java.beans.PropertyChangeListener;
import java.util.Map;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.LookAndFeel;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicMenuItemUI;
import com.formdev.flatlaf.ui.FlatStyleSupport.UnknownStyleException;
/**
* Provides the Flat LaF UI delegate for {@link javax.swing.JMenuItem}.
@@ -56,11 +59,19 @@ public class FlatMenuItemUI
extends BasicMenuItemUI
{
private FlatMenuItemRenderer renderer;
private Map<String, Object> oldStyleValues;
public static ComponentUI createUI( JComponent c ) {
return new FlatMenuItemUI();
}
@Override
public void installUI( JComponent c ) {
super.installUI( c );
applyStyle( FlatStyleSupport.getStyle( menuItem ) );
}
@Override
protected void installDefaults() {
super.installDefaults();
@@ -81,6 +92,44 @@ public class FlatMenuItemUI
return new FlatMenuItemRenderer( menuItem, checkIcon, arrowIcon, acceleratorFont, acceleratorDelimiter );
}
@Override
protected PropertyChangeListener createPropertyChangeListener( JComponent c ) {
return FlatStyleSupport.createPropertyChangeListener( c, this::applyStyle, super.createPropertyChangeListener( c ) );
}
/**
* @since TODO
*/
protected void applyStyle( Object style ) {
oldStyleValues = FlatStyleSupport.parseAndApply( oldStyleValues, style, this::applyStyleProperty );
}
/**
* @since TODO
*/
protected Object applyStyleProperty( String key, Object value ) {
try {
return renderer.applyStyleProperty( key, value );
} catch ( UnknownStyleException ex ) {
// ignore
}
return applyStyleProperty( this, key, value );
}
static Object applyStyleProperty( BasicMenuItemUI ui, String key, Object value ) {
switch( key ) {
case "selectionBackground":
case "selectionForeground":
case "disabledForeground":
case "acceleratorForeground":
case "acceleratorSelectionForeground":
return FlatStyleSupport.applyToField( ui, key, key, value );
default: throw new UnknownStyleException( key );
}
}
@Override
protected Dimension getPreferredMenuItemSize( JComponent c, Icon checkIcon, Icon arrowIcon, int defaultTextIconGap ) {
return renderer.getPreferredMenuItemSize();

View File

@@ -21,6 +21,8 @@ import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeListener;
import java.util.Map;
import javax.swing.ButtonModel;
import javax.swing.Icon;
import javax.swing.JComponent;
@@ -31,6 +33,7 @@ import javax.swing.UIManager;
import javax.swing.event.MouseInputListener;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicMenuUI;
import com.formdev.flatlaf.ui.FlatStyleSupport.UnknownStyleException;
/**
* Provides the Flat LaF UI delegate for {@link javax.swing.JMenu}.
@@ -75,11 +78,19 @@ public class FlatMenuUI
{
private Color hoverBackground;
private FlatMenuItemRenderer renderer;
private Map<String, Object> oldStyleValues;
public static ComponentUI createUI( JComponent c ) {
return new FlatMenuUI();
}
@Override
public void installUI( JComponent c ) {
super.installUI( c );
applyStyle( FlatStyleSupport.getStyle( menuItem ) );
}
@Override
protected void installDefaults() {
super.installDefaults();
@@ -129,6 +140,31 @@ public class FlatMenuUI
};
}
@Override
protected PropertyChangeListener createPropertyChangeListener( JComponent c ) {
return FlatStyleSupport.createPropertyChangeListener( c, this::applyStyle, super.createPropertyChangeListener( c ) );
}
/**
* @since TODO
*/
protected void applyStyle( Object style ) {
oldStyleValues = FlatStyleSupport.parseAndApply( oldStyleValues, style, this::applyStyleProperty );
}
/**
* @since TODO
*/
protected Object applyStyleProperty( String key, Object value ) {
try {
return renderer.applyStyleProperty( key, value );
} catch ( UnknownStyleException ex ) {
// ignore
}
return FlatMenuItemUI.applyStyleProperty( this, key, value );
}
@Override
public Dimension getMinimumSize( JComponent c ) {
// avoid that top-level menus (in menu bar) are made smaller if horizontal space is rare

View File

@@ -18,11 +18,14 @@ package com.formdev.flatlaf.ui;
import java.awt.Dimension;
import java.awt.Graphics;
import java.beans.PropertyChangeListener;
import java.util.Map;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.LookAndFeel;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicRadioButtonMenuItemUI;
import com.formdev.flatlaf.ui.FlatStyleSupport.UnknownStyleException;
/**
* Provides the Flat LaF UI delegate for {@link javax.swing.JRadioButtonMenuItem}.
@@ -56,11 +59,19 @@ public class FlatRadioButtonMenuItemUI
extends BasicRadioButtonMenuItemUI
{
private FlatMenuItemRenderer renderer;
private Map<String, Object> oldStyleValues;
public static ComponentUI createUI( JComponent c ) {
return new FlatRadioButtonMenuItemUI();
}
@Override
public void installUI( JComponent c ) {
super.installUI( c );
applyStyle( FlatStyleSupport.getStyle( menuItem ) );
}
@Override
protected void installDefaults() {
super.installDefaults();
@@ -81,6 +92,31 @@ public class FlatRadioButtonMenuItemUI
return new FlatMenuItemRenderer( menuItem, checkIcon, arrowIcon, acceleratorFont, acceleratorDelimiter );
}
@Override
protected PropertyChangeListener createPropertyChangeListener( JComponent c ) {
return FlatStyleSupport.createPropertyChangeListener( c, this::applyStyle, super.createPropertyChangeListener( c ) );
}
/**
* @since TODO
*/
protected void applyStyle( Object style ) {
oldStyleValues = FlatStyleSupport.parseAndApply( oldStyleValues, style, this::applyStyleProperty );
}
/**
* @since TODO
*/
protected Object applyStyleProperty( String key, Object value ) {
try {
return renderer.applyStyleProperty( key, value );
} catch ( UnknownStyleException ex ) {
// ignore
}
return FlatMenuItemUI.applyStyleProperty( this, key, value );
}
@Override
protected Dimension getPreferredMenuItemSize( JComponent c, Icon checkIcon, Icon arrowIcon, int defaultTextIconGap ) {
return renderer.getPreferredMenuItemSize();

View File

@@ -16,6 +16,7 @@
package com.formdev.flatlaf.ui;
import java.beans.PropertyChangeListener;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -26,6 +27,8 @@ import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Predicate;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.UIManager;
@@ -204,13 +207,38 @@ public class FlatStyleSupport
+ key.substring( dotIndex + 2 );
}
return applyToField( obj, fieldName, key, value, field -> {
Styleable styleable = field.getAnnotation( Styleable.class );
return styleable != null && styleable.dot() == (dotIndex >= 0);
} );
}
/**
* Applies the given value to a field of the given object.
*
* @param obj the object
* @param fieldName the name of the field
* @param key the key (only used for error reporting)
* @param value the new value
* @return the old value of the field
* @throws UnknownStyleException if object does not have a field with given name
* @throws IllegalArgumentException if value type does not fit to expected type 
*/
static Object applyToField( Object obj, String fieldName, String key, Object value )
throws UnknownStyleException, IllegalArgumentException
{
return applyToField( obj, fieldName, key, value, null );
}
private static Object applyToField( Object obj, String fieldName, String key, Object value, Predicate<Field> predicate )
throws UnknownStyleException, IllegalArgumentException
{
Class<?> cls = obj.getClass();
for(;;) {
try {
Field f = cls.getDeclaredField( fieldName );
Styleable styleable = f.getAnnotation( Styleable.class );
if( styleable != null && styleable.dot() == (dotIndex >= 0) ) {
if( predicate == null || predicate.test( f ) ) {
if( Modifier.isFinal( f.getModifiers() ) )
throw new IllegalArgumentException( "field '" + cls.getName() + "." + fieldName + "' is final" );
@@ -234,9 +262,11 @@ public class FlatStyleSupport
if( cls == null )
throw new UnknownStyleException( key );
String superclassName = cls.getName();
if( superclassName.startsWith( "java." ) || superclassName.startsWith( "javax." ) )
throw new UnknownStyleException( key );
if( predicate != null ) {
String superclassName = cls.getName();
if( superclassName.startsWith( "java." ) || superclassName.startsWith( "javax." ) )
throw new UnknownStyleException( key );
}
}
}
@@ -244,6 +274,21 @@ public class FlatStyleSupport
return c.getClientProperty( FlatClientProperties.STYLE );
}
static PropertyChangeListener createPropertyChangeListener( JComponent c,
Consumer<Object> applyStyle, PropertyChangeListener superListener )
{
return e -> {
if( superListener != null )
superListener.propertyChange( e );
if( FlatClientProperties.STYLE.equals( e.getPropertyName() ) ) {
applyStyle.accept( e.getNewValue() );
c.revalidate();
c.repaint();
}
};
}
static Border cloneBorder( Border border ) {
Class<? extends Border> borderClass = border.getClass();
try {

View File

@@ -23,23 +23,9 @@ import java.awt.Insets;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;
import javax.swing.AbstractButton;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JEditorPane;
import javax.swing.JFormattedTextField;
import javax.swing.JPasswordField;
import javax.swing.JRadioButton;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.JToggleButton;
import javax.swing.UIManager;
import javax.swing.*;
import org.junit.jupiter.api.Test;
import com.formdev.flatlaf.icons.FlatCapsLockIcon;
import com.formdev.flatlaf.icons.FlatCheckBoxIcon;
import com.formdev.flatlaf.icons.FlatRadioButtonIcon;
import com.formdev.flatlaf.icons.*;
/**
* @author Karl Tauber
@@ -157,6 +143,95 @@ public class FlatStylingTests
textField( ui );
}
@Test
void menu() {
UIManager.put( "Menu.arrowIcon", new FlatMenuArrowIcon() );
UIManager.put( "Menu.checkIcon", null );
FlatMenuUI ui = new FlatMenuUI();
ui.installUI( new JMenu() );
Consumer<String> applyStyle = style -> ui.applyStyle( style );
menuItem( applyStyle );
menuItem_arrowIcon( applyStyle );
}
@Test
void menuItem() {
UIManager.put( "MenuItem.arrowIcon", new FlatMenuItemArrowIcon() );
UIManager.put( "MenuItem.checkIcon", null );
FlatMenuItemUI ui = new FlatMenuItemUI();
ui.installUI( new JMenuItem() );
Consumer<String> applyStyle = style -> ui.applyStyle( style );
menuItem( applyStyle );
menuItem_arrowIcon( applyStyle );
}
@Test
void checkBoxMenuItem() {
UIManager.put( "CheckBoxMenuItem.arrowIcon", new FlatMenuItemArrowIcon() );
UIManager.put( "CheckBoxMenuItem.checkIcon", new FlatCheckBoxMenuItemIcon() );
FlatCheckBoxMenuItemUI ui = new FlatCheckBoxMenuItemUI();
ui.installUI( new JCheckBoxMenuItem() );
Consumer<String> applyStyle = style -> ui.applyStyle( style );
menuItem( applyStyle );
menuItem_arrowIcon( applyStyle );
menuItem_checkIcon( applyStyle );
}
@Test
void radioButtonMenuItem() {
UIManager.put( "RadioButtonMenuItem.arrowIcon", new FlatMenuItemArrowIcon() );
UIManager.put( "RadioButtonMenuItem.checkIcon", new FlatRadioButtonMenuItemIcon() );
FlatRadioButtonMenuItemUI ui = new FlatRadioButtonMenuItemUI();
ui.installUI( new JRadioButtonMenuItem() );
Consumer<String> applyStyle = style -> ui.applyStyle( style );
menuItem( applyStyle );
menuItem_arrowIcon( applyStyle );
menuItem_checkIcon( applyStyle );
}
private void menuItem( Consumer<String> applyStyle ) {
applyStyle.accept( "selectionBackground: #fff" );
applyStyle.accept( "selectionForeground: #fff" );
applyStyle.accept( "disabledForeground: #fff" );
applyStyle.accept( "acceleratorForeground: #fff" );
applyStyle.accept( "acceleratorSelectionForeground: #fff" );
menuItemRenderer( applyStyle );
}
private void menuItemRenderer( Consumer<String> applyStyle ) {
applyStyle.accept( "minimumWidth: 10" );
applyStyle.accept( "minimumIconSize: 16,16" );
applyStyle.accept( "textAcceleratorGap: 28" );
applyStyle.accept( "textNoAcceleratorGap: 6" );
applyStyle.accept( "acceleratorArrowGap: 2" );
applyStyle.accept( "checkBackground: #fff" );
applyStyle.accept( "checkMargins: 1,2,3,4" );
applyStyle.accept( "underlineSelectionBackground: #fff" );
applyStyle.accept( "underlineSelectionCheckBackground: #fff" );
applyStyle.accept( "underlineSelectionColor: #fff" );
applyStyle.accept( "underlineSelectionHeight: 3" );
}
private void menuItem_checkIcon( Consumer<String> applyStyle ) {
applyStyle.accept( "icon.checkmarkColor: #fff" );
applyStyle.accept( "icon.disabledCheckmarkColor: #fff" );
applyStyle.accept( "icon.selectionForeground: #fff" );
}
private void menuItem_arrowIcon( Consumer<String> applyStyle ) {
applyStyle.accept( "icon.arrowType: chevron" );
applyStyle.accept( "icon.arrowColor: #fff" );
applyStyle.accept( "icon.disabledArrowColor: #fff" );
applyStyle.accept( "selectionForeground: #fff" );
}
@Test
void passwordField() {
FlatPasswordFieldUI ui = new FlatPasswordFieldUI();
@@ -556,4 +631,47 @@ public class FlatStylingTests
icon.applyStyleProperty( "pressedBackground", Color.WHITE );
icon.applyStyleProperty( "selectedPressedBackground", Color.WHITE );
}
@Test
void flatCheckBoxMenuItemIcon() {
FlatCheckBoxMenuItemIcon icon = new FlatCheckBoxMenuItemIcon();
flatCheckBoxMenuItemIcon( icon );
}
@Test
void flatRadioButtonMenuItemIcon() {
FlatRadioButtonMenuItemIcon icon = new FlatRadioButtonMenuItemIcon();
// FlatRadioButtonMenuItemIcon extends FlatCheckBoxMenuItemIcon
flatCheckBoxMenuItemIcon( icon );
}
private void flatCheckBoxMenuItemIcon( FlatCheckBoxMenuItemIcon icon ) {
icon.applyStyleProperty( "checkmarkColor", Color.WHITE );
icon.applyStyleProperty( "disabledCheckmarkColor", Color.WHITE );
icon.applyStyleProperty( "selectionForeground", Color.WHITE );
}
@Test
void flatMenuArrowIcon() {
FlatMenuArrowIcon icon = new FlatMenuArrowIcon();
flatMenuArrowIcon( icon );
}
@Test
void flatMenuItemArrowIcon() {
FlatMenuItemArrowIcon icon = new FlatMenuItemArrowIcon();
// FlatMenuItemArrowIcon extends FlatMenuArrowIcon
flatMenuArrowIcon( icon );
}
private void flatMenuArrowIcon( FlatMenuArrowIcon icon ) {
icon.applyStyleProperty( "arrowType", "chevron" );
icon.applyStyleProperty( "arrowColor", Color.WHITE );
icon.applyStyleProperty( "disabledArrowColor", Color.WHITE );
icon.applyStyleProperty( "selectionForeground", Color.WHITE );
}
}