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 77d3b5fa..4daf92d7 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 @@ -31,6 +31,7 @@ import java.awt.Rectangle; import java.awt.geom.RoundRectangle2D; import java.beans.PropertyChangeEvent; import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; import javax.swing.AbstractButton; import javax.swing.ButtonModel; import javax.swing.Icon; @@ -40,7 +41,6 @@ import javax.swing.JToggleButton; import javax.swing.JToolBar; import javax.swing.LookAndFeel; import javax.swing.UIManager; -import javax.swing.border.Border; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.UIResource; import javax.swing.plaf.basic.BasicButtonListener; @@ -137,10 +137,10 @@ public class FlatButtonUI private Icon helpButtonIcon; private final boolean shared; - private boolean borderShared = true; private boolean helpButtonIconShared = true; private boolean defaults_initialized = false; private Map oldStyleValues; + private AtomicBoolean borderShared; public static ComponentUI createUI( JComponent c ) { return FlatUIUtils.canUseSharedUI( c ) @@ -223,6 +223,7 @@ public class FlatButtonUI super.uninstallDefaults( b ); oldStyleValues = null; + borderShared = null; MigLayoutVisualPadding.uninstall( b ); defaults_initialized = false; @@ -289,25 +290,9 @@ public class FlatButtonUI return ((FlatHelpButtonIcon)helpButtonIcon).applyStyleProperty( key, value ); } - try { - return FlatStyleSupport.applyToAnnotatedObject( this, key, value ); - } catch( UnknownStyleException ex ) { - Border border = b.getBorder(); - if( border instanceof FlatBorder ) { - if( borderShared ) { - border = FlatStyleSupport.cloneBorder( border ); - b.setBorder( border ); - borderShared = false; - } - - try { - return ((FlatBorder)border).applyStyleProperty( key, value ); - } catch( UnknownStyleException ex2 ) { - // ignore - } - } - throw ex; - } + if( borderShared == null ) + borderShared = new AtomicBoolean( true ); + return FlatStyleSupport.applyToAnnotatedObjectOrBorder( this, key, value, b, borderShared ); } static boolean isContentAreaFilled( Component c ) { diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatComboBoxUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatComboBoxUI.java index de802eee..146c4414 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatComboBoxUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatComboBoxUI.java @@ -41,6 +41,7 @@ import java.awt.geom.Rectangle2D; import java.beans.PropertyChangeListener; import java.lang.ref.WeakReference; import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; import javax.swing.AbstractAction; import javax.swing.BorderFactory; import javax.swing.CellRendererPane; @@ -141,6 +142,7 @@ public class FlatComboBoxUI private WeakReference lastRendererComponent; private Map oldStyleValues; + private AtomicBoolean borderShared; public static ComponentUI createUI( JComponent c ) { return new FlatComboBoxUI(); @@ -261,6 +263,7 @@ public class FlatComboBoxUI popupFocusedBackground = null; oldStyleValues = null; + borderShared = null; MigLayoutVisualPadding.uninstall( comboBox ); } @@ -440,7 +443,9 @@ public class FlatComboBoxUI * @since TODO */ protected Object applyStyleProperty( String key, Object value ) { - return FlatStyleSupport.applyToAnnotatedObject( this, key, value ); + if( borderShared == null ) + borderShared = new AtomicBoolean( true ); + return FlatStyleSupport.applyToAnnotatedObjectOrBorder( this, key, value, comboBox, borderShared ); } @Override diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatPasswordFieldUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatPasswordFieldUI.java index 822a9b34..d81c267a 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatPasswordFieldUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatPasswordFieldUI.java @@ -27,18 +27,17 @@ import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.beans.PropertyChangeEvent; import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; import javax.swing.Icon; import javax.swing.JComponent; import javax.swing.LookAndFeel; import javax.swing.UIManager; -import javax.swing.border.Border; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.basic.BasicPasswordFieldUI; import javax.swing.text.Caret; import javax.swing.text.JTextComponent; import com.formdev.flatlaf.icons.FlatCapsLockIcon; import com.formdev.flatlaf.ui.FlatStyleSupport.Styleable; -import com.formdev.flatlaf.ui.FlatStyleSupport.UnknownStyleException; import com.formdev.flatlaf.util.HiDPIUtils; /** @@ -92,7 +91,7 @@ public class FlatPasswordFieldUI private FocusListener focusListener; private KeyListener capsLockListener; private Map oldStyleValues; - private boolean borderShared = true; + private AtomicBoolean borderShared; private boolean capsLockIconShared = true; public static ComponentUI createUI( JComponent c ) { @@ -141,6 +140,7 @@ public class FlatPasswordFieldUI oldInactiveBackground = null; oldStyleValues = null; + borderShared = null; MigLayoutVisualPadding.uninstall( getComponent() ); } @@ -222,25 +222,9 @@ public class FlatPasswordFieldUI return ((FlatCapsLockIcon)capsLockIcon).applyStyleProperty( key, value ); } - try { - return FlatStyleSupport.applyToAnnotatedObject( this, key, value ); - } catch( UnknownStyleException ex ) { - Border border = getComponent().getBorder(); - if( border instanceof FlatBorder ) { - if( borderShared ) { - border = FlatStyleSupport.cloneBorder( border ); - getComponent().setBorder( border ); - borderShared = false; - } - - try { - return ((FlatBorder)border).applyStyleProperty( key, value ); - } catch( UnknownStyleException ex2 ) { - // ignore - } - } - throw ex; - } + if( borderShared == null ) + borderShared = new AtomicBoolean( true ); + return FlatStyleSupport.applyToAnnotatedObjectOrBorder( this, key, value, getComponent(), borderShared ); } private void updateBackground() { diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatRoundBorder.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatRoundBorder.java index 3703be9c..975c71e0 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatRoundBorder.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatRoundBorder.java @@ -18,6 +18,7 @@ package com.formdev.flatlaf.ui; import java.awt.Component; import javax.swing.UIManager; +import com.formdev.flatlaf.ui.FlatStyleSupport.Styleable; /** * Border for various components (e.g. {@link javax.swing.JComboBox}). @@ -29,7 +30,7 @@ import javax.swing.UIManager; public class FlatRoundBorder extends FlatBorder { - protected final int arc = UIManager.getInt( "Component.arc" ); + @Styleable protected int arc = UIManager.getInt( "Component.arc" ); @Override protected int getArc( Component c ) { diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatSpinnerUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatSpinnerUI.java index 84e53e6a..c230a82f 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatSpinnerUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatSpinnerUI.java @@ -33,6 +33,7 @@ import java.awt.geom.Rectangle2D; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; import javax.swing.JComponent; import javax.swing.JSpinner; import javax.swing.JTextField; @@ -100,6 +101,7 @@ public class FlatSpinnerUI @Styleable protected Insets padding; private Map oldStyleValues; + private AtomicBoolean borderShared; public static ComponentUI createUI( JComponent c ) { return new FlatSpinnerUI(); @@ -154,6 +156,7 @@ public class FlatSpinnerUI padding = null; oldStyleValues = null; + borderShared = null; MigLayoutVisualPadding.uninstall( spinner ); } @@ -196,7 +199,9 @@ public class FlatSpinnerUI * @since TODO */ protected Object applyStyleProperty( String key, Object value ) { - return FlatStyleSupport.applyToAnnotatedObject( this, key, value ); + if( borderShared == null ) + borderShared = new AtomicBoolean( true ); + return FlatStyleSupport.applyToAnnotatedObjectOrBorder( this, key, value, spinner, borderShared ); } @Override diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatStyleSupport.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatStyleSupport.java index 23ad2c3f..902f79b3 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatStyleSupport.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatStyleSupport.java @@ -26,6 +26,7 @@ import java.lang.reflect.Modifier; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.BiFunction; import java.util.function.Consumer; import java.util.function.Predicate; @@ -270,6 +271,30 @@ public class FlatStyleSupport } } + static Object applyToAnnotatedObjectOrBorder( Object obj, String key, Object value, + JComponent c, AtomicBoolean borderShared ) + { + try { + return applyToAnnotatedObject( obj, key, value ); + } catch( UnknownStyleException ex ) { + Border border = c.getBorder(); + if( border instanceof FlatBorder ) { + if( borderShared.get() ) { + border = cloneBorder( border ); + c.setBorder( border ); + borderShared.set( false ); + } + + try { + return ((FlatBorder)border).applyStyleProperty( key, value ); + } catch( UnknownStyleException ex2 ) { + // ignore + } + } + throw ex; + } + } + public static Object getStyle( JComponent c ) { return c.getClientProperty( FlatClientProperties.STYLE ); } diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTextFieldUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTextFieldUI.java index 650a8ae2..fce393f2 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTextFieldUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTextFieldUI.java @@ -27,6 +27,7 @@ import java.awt.Insets; import java.awt.event.FocusListener; import java.beans.PropertyChangeEvent; import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Consumer; import javax.swing.JComboBox; import javax.swing.JComponent; @@ -34,7 +35,6 @@ import javax.swing.JSpinner; import javax.swing.JTextField; import javax.swing.LookAndFeel; import javax.swing.UIManager; -import javax.swing.border.Border; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.UIResource; import javax.swing.plaf.basic.BasicTextFieldUI; @@ -42,7 +42,6 @@ import javax.swing.text.Caret; import javax.swing.text.JTextComponent; import com.formdev.flatlaf.FlatClientProperties; import com.formdev.flatlaf.ui.FlatStyleSupport.Styleable; -import com.formdev.flatlaf.ui.FlatStyleSupport.UnknownStyleException; import com.formdev.flatlaf.util.HiDPIUtils; import com.formdev.flatlaf.util.JavaCompatibility; @@ -91,7 +90,7 @@ public class FlatTextFieldUI private FocusListener focusListener; private Map oldStyleValues; - private boolean borderShared = true; + private AtomicBoolean borderShared; public static ComponentUI createUI( JComponent c ) { return new FlatTextFieldUI(); @@ -136,6 +135,7 @@ public class FlatTextFieldUI oldInactiveBackground = null; oldStyleValues = null; + borderShared = null; MigLayoutVisualPadding.uninstall( getComponent() ); } @@ -208,25 +208,9 @@ public class FlatTextFieldUI * @since TODO */ protected Object applyStyleProperty( String key, Object value ) { - try { - return FlatStyleSupport.applyToAnnotatedObject( this, key, value ); - } catch( UnknownStyleException ex ) { - Border border = getComponent().getBorder(); - if( border instanceof FlatBorder ) { - if( borderShared ) { - border = FlatStyleSupport.cloneBorder( border ); - getComponent().setBorder( border ); - borderShared = false; - } - - try { - return ((FlatBorder)border).applyStyleProperty( key, value ); - } catch( UnknownStyleException ex2 ) { - // ignore - } - } - throw ex; - } + if( borderShared == null ) + borderShared = new AtomicBoolean( true ); + return FlatStyleSupport.applyToAnnotatedObjectOrBorder( this, key, value, getComponent(), borderShared ); } private void updateBackground() { diff --git a/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/FlatStylingTests.java b/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/FlatStylingTests.java index 635f5da2..58bc68c8 100644 --- a/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/FlatStylingTests.java +++ b/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/FlatStylingTests.java @@ -141,7 +141,8 @@ public class FlatStylingTests void comboBox() { FlatComboBoxUI ui = new FlatComboBoxUI(); - // create arrow button + // create border and arrow button + UIManager.put( "ComboBox.border", new FlatRoundBorder() ); ui.installUI( new JComboBox<>() ); ui.applyStyle( "minimumWidth: 100" ); @@ -165,6 +166,9 @@ public class FlatStylingTests ui.applyStyle( "buttonPressedArrowColor: #fff" ); ui.applyStyle( "popupFocusedBackground: #fff" ); + + // border + flatRoundBorder( style -> ui.applyStyle( style ) ); } @Test @@ -465,7 +469,8 @@ public class FlatStylingTests void spinner() { FlatSpinnerUI ui = new FlatSpinnerUI(); - // create arrow buttons + // create border and arrow buttons + UIManager.put( "Spinner.border", new FlatRoundBorder() ); ui.installUI( new JSpinner() ); ui.applyStyle( "minimumWidth: 100" ); @@ -482,6 +487,9 @@ public class FlatStylingTests ui.applyStyle( "buttonHoverArrowColor: #fff" ); ui.applyStyle( "buttonPressedArrowColor: #fff" ); ui.applyStyle( "padding: 1,2,3,4" ); + + // border + flatRoundBorder( style -> ui.applyStyle( style ) ); } @Test @@ -664,6 +672,12 @@ public class FlatStylingTests applyStyle.accept( "arc: 6" ); } + private void flatRoundBorder( Consumer applyStyle ) { + flatBorder( applyStyle ); + + applyStyle.accept( "arc: 6" ); + } + private void flatTextBorder( Consumer applyStyle ) { flatBorder( applyStyle );