mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2025-12-07 14:30:56 +03:00
Styling: support Menu, MenuItem, CheckBoxMenuItem and RadioButtonMenuItem
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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 ) );
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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 ) {
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user