diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java
index c601eca4..f4b4e03d 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java
@@ -145,6 +145,38 @@ public interface FlatClientProperties
*/
String STYLE = "FlatLaf.style";
+ /**
+ * Specifies the style class(es) of a component as String
+ * or as {@link java.util.List}<String>.
+ *
+ * The style rules must be defined in UI defaults either as strings (in CSS syntax)
+ * or as {@link java.util.Map}<String, Object> (with binary values).
+ * The key must be in syntax: {@code [style]type.styleClass}, where the type is optional.
+ * E.g. in FlatLaf properties file:
+ *
{@code
+ * [style]Button.primary = borderColor: #08f; background: #08f; foreground: #fff
+ * [style].secondary = borderColor: #0f8; background: #0f8
+ * }
+ * or in Java code:
+ * {@code
+ * UIManager.put( "[style]Button.primary", "borderColor: #08f; background: #08f; foreground: #fff" );
+ * UIManager.put( "[style].secondary", "borderColor: #0f8; background: #0f8" );
+ * }
+ * The rule "Button.primary" can be applied to buttons only.
+ * The rule ".secondary" can be applied to any component.
+ *
+ * To have similar behaviour as in CSS, first the rule without type is applied,
+ * then the rule with type.
+ * E.g. setting style class to "foo" on a {@code JButton} uses rules
+ * from UI default keys "[style].foo" and "[style]Button.foo".
+ *
+ * Components {@link javax.swing.JComponent}
+ * Value type {@link java.lang.String}, {@code String[]} or {@link java.util.List}<String>
+ *
+ * @since 2
+ */
+ String STYLE_CLASS = "FlatLaf.styleClass";
+
/**
* Specifies minimum width of a component.
*
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 0465e7d0..a29c4626 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
@@ -152,6 +152,7 @@ public class FlatButtonUI
: new FlatButtonUI( false );
}
+ /** @since 2 */
protected FlatButtonUI( boolean shared ) {
this.shared = shared;
}
@@ -160,7 +161,7 @@ public class FlatButtonUI
public void installUI( JComponent c ) {
super.installUI( c );
- applyStyle( (AbstractButton) c, FlatStylingSupport.getStyle( c ) );
+ installStyle( (AbstractButton) c );
}
@Override
@@ -254,19 +255,29 @@ public class FlatButtonUI
break;
case STYLE:
- Object style = e.getNewValue();
- if( style != null && shared ) {
+ case STYLE_CLASS:
+ if( shared && FlatStylingSupport.hasStyleProperty( b ) ) {
// unshare component UI if necessary
// updateUI() invokes applyStyle() from installUI()
b.updateUI();
} else
- applyStyle( b, style );
+ installStyle( b );
b.revalidate();
b.repaint();
break;
}
}
+ /** @since 2 */
+ protected void installStyle( AbstractButton b ) {
+ applyStyle( b, FlatStylingSupport.getResolvedStyle( b, getStyleType() ) );
+ }
+
+ /** @since 2 */
+ String getStyleType() {
+ return "Button";
+ }
+
/** @since 2 */
protected void applyStyle( AbstractButton b, Object style ) {
oldStyleValues = FlatStylingSupport.parseAndApply( oldStyleValues, style,
diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatCheckBoxMenuItemUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatCheckBoxMenuItemUI.java
index 5db876ba..b78ca31d 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatCheckBoxMenuItemUI.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatCheckBoxMenuItemUI.java
@@ -72,7 +72,7 @@ public class FlatCheckBoxMenuItemUI
public void installUI( JComponent c ) {
super.installUI( c );
- applyStyle( FlatStylingSupport.getStyle( menuItem ) );
+ installStyle();
}
@Override
@@ -98,7 +98,12 @@ public class FlatCheckBoxMenuItemUI
@Override
protected PropertyChangeListener createPropertyChangeListener( JComponent c ) {
- return FlatStylingSupport.createPropertyChangeListener( c, this::applyStyle, super.createPropertyChangeListener( c ) );
+ return FlatStylingSupport.createPropertyChangeListener( c, this::installStyle, super.createPropertyChangeListener( c ) );
+ }
+
+ /** @since 2 */
+ protected void installStyle() {
+ applyStyle( FlatStylingSupport.getResolvedStyle( menuItem, "CheckBoxMenuItem" ) );
}
/** @since 2 */
diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatCheckBoxUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatCheckBoxUI.java
index 0c407fd6..354b30b1 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatCheckBoxUI.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatCheckBoxUI.java
@@ -57,4 +57,10 @@ public class FlatCheckBoxUI
public String getPropertyPrefix() {
return "CheckBox.";
}
+
+ /** @since 2 */
+ @Override
+ String getStyleType() {
+ return "CheckBox";
+ }
}
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 1d438c7e..25f086bf 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
@@ -16,6 +16,7 @@
package com.formdev.flatlaf.ui;
+import static com.formdev.flatlaf.FlatClientProperties.*;
import static com.formdev.flatlaf.util.UIScale.scale;
import static com.formdev.flatlaf.util.UIScale.unscale;
import java.awt.Color;
@@ -69,7 +70,6 @@ import javax.swing.plaf.basic.BasicComboBoxUI;
import javax.swing.plaf.basic.BasicComboPopup;
import javax.swing.plaf.basic.ComboPopup;
import javax.swing.text.JTextComponent;
-import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
import com.formdev.flatlaf.util.SystemInfo;
@@ -155,7 +155,7 @@ public class FlatComboBoxUI
public void installUI( JComponent c ) {
super.installUI( c );
- applyStyle( FlatStylingSupport.getStyle( comboBox ) );
+ installStyle();
}
@Override
@@ -341,16 +341,28 @@ public class FlatComboBoxUI
} else if( editor != null && source == comboBox && propertyName == "componentOrientation" ) {
ComponentOrientation o = (ComponentOrientation) e.getNewValue();
editor.applyComponentOrientation( o );
- } else if( editor != null && FlatClientProperties.PLACEHOLDER_TEXT.equals( propertyName ) )
- editor.repaint();
- else if( FlatClientProperties.COMPONENT_ROUND_RECT.equals( propertyName ) )
- comboBox.repaint();
- else if( FlatClientProperties.MINIMUM_WIDTH.equals( propertyName ) )
- comboBox.revalidate();
- else if( FlatClientProperties.STYLE.equals( propertyName ) ) {
- applyStyle( e.getNewValue() );
- comboBox.revalidate();
- comboBox.repaint();
+ } else {
+ switch( propertyName ) {
+ case PLACEHOLDER_TEXT:
+ if( editor != null )
+ editor.repaint();
+ break;
+
+ case COMPONENT_ROUND_RECT:
+ comboBox.repaint();
+ break;
+
+ case MINIMUM_WIDTH:
+ comboBox.revalidate();
+ break;
+
+ case STYLE:
+ case STYLE_CLASS:
+ installStyle();
+ comboBox.revalidate();
+ comboBox.repaint();
+ break;
+ }
}
};
}
@@ -419,7 +431,7 @@ public class FlatComboBoxUI
unscale( Math.max( scale( padding.right ) - insets.right, 0 ) )
);
}
- textField.putClientProperty( FlatClientProperties.TEXT_FIELD_PADDING, pad );
+ textField.putClientProperty( TEXT_FIELD_PADDING, pad );
}
private void updateEditorColors() {
@@ -438,6 +450,11 @@ public class FlatComboBoxUI
return new FlatComboBoxButton();
}
+ /** @since 2 */
+ protected void installStyle() {
+ applyStyle( FlatStylingSupport.getResolvedStyle( comboBox, "ComboBox" ) );
+ }
+
/** @since 2 */
protected void applyStyle( Object style ) {
Insets oldPadding = padding;
diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatEditorPaneUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatEditorPaneUI.java
index 3fe21d52..6c9cb714 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatEditorPaneUI.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatEditorPaneUI.java
@@ -25,7 +25,6 @@ import java.awt.Insets;
import java.awt.event.FocusListener;
import java.beans.PropertyChangeEvent;
import java.util.Map;
-import java.util.function.Consumer;
import javax.swing.JComponent;
import javax.swing.JEditorPane;
import javax.swing.UIManager;
@@ -91,7 +90,7 @@ public class FlatEditorPaneUI
public void installUI( JComponent c ) {
super.installUI( c );
- applyStyle( FlatStylingSupport.getStyle( c ) );
+ installStyle();
}
@Override
@@ -155,23 +154,29 @@ public class FlatEditorPaneUI
updateBackground();
super.propertyChange( e );
- propertyChange( getComponent(), e, this::applyStyle );
+ propertyChange( getComponent(), e, this::installStyle );
}
- static void propertyChange( JTextComponent c, PropertyChangeEvent e, Consumer applyStyle ) {
+ static void propertyChange( JTextComponent c, PropertyChangeEvent e, Runnable installStyle ) {
switch( e.getPropertyName() ) {
case FlatClientProperties.MINIMUM_WIDTH:
c.revalidate();
break;
case FlatClientProperties.STYLE:
- applyStyle.accept( e.getNewValue() );
+ case FlatClientProperties.STYLE_CLASS:
+ installStyle.run();
c.revalidate();
c.repaint();
break;
}
}
+ /** @since 2 */
+ protected void installStyle() {
+ applyStyle( FlatStylingSupport.getResolvedStyle( getComponent(), "EditorPane" ) );
+ }
+
/** @since 2 */
protected void applyStyle( Object style ) {
oldDisabledBackground = disabledBackground;
diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatFormattedTextFieldUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatFormattedTextFieldUI.java
index 6e34a643..5f390de8 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatFormattedTextFieldUI.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatFormattedTextFieldUI.java
@@ -60,4 +60,10 @@ public class FlatFormattedTextFieldUI
protected String getPropertyPrefix() {
return "FormattedTextField";
}
+
+ /** @since 2 */
+ @Override
+ String getStyleType() {
+ return "FormattedTextField";
+ }
}
diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatInternalFrameUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatInternalFrameUI.java
index b11acd16..32460cda 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatInternalFrameUI.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatInternalFrameUI.java
@@ -116,7 +116,7 @@ public class FlatInternalFrameUI
windowResizer = createWindowResizer();
- applyStyle( FlatStylingSupport.getStyle( c ) );
+ installStyle();
}
@Override
@@ -148,10 +148,15 @@ public class FlatInternalFrameUI
@Override
protected PropertyChangeListener createPropertyChangeListener() {
- return FlatStylingSupport.createPropertyChangeListener( frame, this::applyStyle,
+ return FlatStylingSupport.createPropertyChangeListener( frame, this::installStyle,
super.createPropertyChangeListener() );
}
+ /** @since 2 */
+ protected void installStyle() {
+ applyStyle( FlatStylingSupport.getResolvedStyle( frame, "InternalFrame" ) );
+ }
+
/** @since 2 */
protected void applyStyle( Object style ) {
oldStyleValues = FlatStylingSupport.parseAndApply( oldStyleValues, style, this::applyStyleProperty );
diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatLabelUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatLabelUI.java
index e90e4df5..2c16494a 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatLabelUI.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatLabelUI.java
@@ -81,7 +81,7 @@ public class FlatLabelUI
public void installUI( JComponent c ) {
super.installUI( c );
- applyStyle( (JLabel) c, FlatStylingSupport.getStyle( c ) );
+ installStyle( (JLabel) c );
}
@Override
@@ -117,21 +117,25 @@ public class FlatLabelUI
if( name == "text" || name == "font" || name == "foreground" ) {
JLabel label = (JLabel) e.getSource();
updateHTMLRenderer( label, label.getText(), true );
- } else if( name.equals( FlatClientProperties.STYLE ) ) {
+ } else if( name.equals( FlatClientProperties.STYLE ) || name.equals( FlatClientProperties.STYLE_CLASS ) ) {
JLabel label = (JLabel) e.getSource();
- Object style = e.getNewValue();
- if( style != null && shared ) {
+ if( shared && FlatStylingSupport.hasStyleProperty( label ) ) {
// unshare component UI if necessary
// updateUI() invokes applyStyle() from installUI()
label.updateUI();
} else
- applyStyle( label, style );
+ installStyle( label );
label.revalidate();
label.repaint();
} else
super.propertyChange( e );
}
+ /** @since 2 */
+ protected void installStyle( JLabel c ) {
+ applyStyle( c, FlatStylingSupport.getResolvedStyle( c, "Label" ) );
+ }
+
/** @since 2 */
protected void applyStyle( JLabel c, Object style ) {
oldStyleValues = FlatStylingSupport.parseAndApply( oldStyleValues, style,
diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatListUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatListUI.java
index 9e1cb035..956c6b76 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatListUI.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatListUI.java
@@ -91,7 +91,7 @@ public class FlatListUI
public void installUI( JComponent c ) {
super.installUI( c );
- applyStyle( FlatStylingSupport.getStyle( c ) );
+ installStyle();
}
@Override
@@ -151,7 +151,8 @@ public class FlatListUI
break;
case FlatClientProperties.STYLE:
- applyStyle( e.getNewValue() );
+ case FlatClientProperties.STYLE_CLASS:
+ installStyle();
list.revalidate();
list.repaint();
break;
@@ -159,6 +160,11 @@ public class FlatListUI
};
}
+ /** @since 2 */
+ protected void installStyle() {
+ applyStyle( FlatStylingSupport.getResolvedStyle( list, "List" ) );
+ }
+
/** @since 2 */
protected void applyStyle( Object style ) {
Color oldSelectionBackground = selectionBackground;
diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuBarUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuBarUI.java
index 2e09ecf4..a0e5280a 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuBarUI.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuBarUI.java
@@ -39,7 +39,6 @@ import javax.swing.plaf.ActionMapUIResource;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.UIResource;
import javax.swing.plaf.basic.BasicMenuBarUI;
-import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.FlatLaf;
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
@@ -91,7 +90,7 @@ public class FlatMenuBarUI
public void installUI( JComponent c ) {
super.installUI( c );
- applyStyle( FlatStylingSupport.getStyle( c ) );
+ installStyle();
}
@Override
@@ -113,16 +112,15 @@ public class FlatMenuBarUI
protected void installListeners() {
super.installListeners();
- propertyChangeListener = FlatStylingSupport.createPropertyChangeListener(
- menuBar, this::applyStyle, null );
- menuBar.addPropertyChangeListener( FlatClientProperties.STYLE, propertyChangeListener );
+ propertyChangeListener = FlatStylingSupport.createPropertyChangeListener( menuBar, this::installStyle, null );
+ menuBar.addPropertyChangeListener( propertyChangeListener );
}
@Override
protected void uninstallListeners() {
super.uninstallListeners();
- menuBar.removePropertyChangeListener( FlatClientProperties.STYLE, propertyChangeListener );
+ menuBar.removePropertyChangeListener( propertyChangeListener );
propertyChangeListener = null;
}
@@ -138,6 +136,11 @@ public class FlatMenuBarUI
map.put( "takeFocus", new TakeFocus() );
}
+ /** @since 2 */
+ protected void installStyle() {
+ applyStyle( FlatStylingSupport.getResolvedStyle( menuBar, "MenuBar" ) );
+ }
+
/** @since 2 */
protected void applyStyle( Object style ) {
oldStyleValues = FlatStylingSupport.parseAndApply( oldStyleValues, style, this::applyStyleProperty );
diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuItemUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuItemUI.java
index 541d0c5a..0b7b9516 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuItemUI.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuItemUI.java
@@ -73,7 +73,7 @@ public class FlatMenuItemUI
public void installUI( JComponent c ) {
super.installUI( c );
- applyStyle( FlatStylingSupport.getStyle( menuItem ) );
+ installStyle();
}
@Override
@@ -99,7 +99,12 @@ public class FlatMenuItemUI
@Override
protected PropertyChangeListener createPropertyChangeListener( JComponent c ) {
- return FlatStylingSupport.createPropertyChangeListener( c, this::applyStyle, super.createPropertyChangeListener( c ) );
+ return FlatStylingSupport.createPropertyChangeListener( c, this::installStyle, super.createPropertyChangeListener( c ) );
+ }
+
+ /** @since 2 */
+ protected void installStyle() {
+ applyStyle( FlatStylingSupport.getResolvedStyle( menuItem, "MenuItem" ) );
}
/** @since 2 */
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 2805f529..009c505a 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
@@ -92,7 +92,7 @@ public class FlatMenuUI
public void installUI( JComponent c ) {
super.installUI( c );
- applyStyle( FlatStylingSupport.getStyle( menuItem ) );
+ installStyle();
}
@Override
@@ -145,7 +145,12 @@ public class FlatMenuUI
@Override
protected PropertyChangeListener createPropertyChangeListener( JComponent c ) {
- return FlatStylingSupport.createPropertyChangeListener( c, this::applyStyle, super.createPropertyChangeListener( c ) );
+ return FlatStylingSupport.createPropertyChangeListener( c, this::installStyle, super.createPropertyChangeListener( c ) );
+ }
+
+ /** @since 2 */
+ protected void installStyle() {
+ applyStyle( FlatStylingSupport.getResolvedStyle( menuItem, "Menu" ) );
}
/** @since 2 */
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 56438e23..69c93889 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
@@ -162,6 +162,12 @@ public class FlatPasswordFieldUI
}
}
+ /** @since 2 */
+ @Override
+ String getStyleType() {
+ return "PasswordField";
+ }
+
/** @since 2 */
@Override
protected Object applyStyleProperty( String key, Object value ) {
diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatPopupMenuSeparatorUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatPopupMenuSeparatorUI.java
index 136983f9..c0837476 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatPopupMenuSeparatorUI.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatPopupMenuSeparatorUI.java
@@ -53,4 +53,10 @@ public class FlatPopupMenuSeparatorUI
protected String getPropertyPrefix() {
return "PopupMenuSeparator";
}
+
+ /** @since 2 */
+ @Override
+ String getStyleType() {
+ return "PopupMenuSeparator";
+ }
}
diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatPopupMenuUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatPopupMenuUI.java
index 78d348ed..1b7c1b12 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatPopupMenuUI.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatPopupMenuUI.java
@@ -22,7 +22,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
import javax.swing.JComponent;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicPopupMenuUI;
-import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
/**
@@ -53,7 +52,7 @@ public class FlatPopupMenuUI
public void installUI( JComponent c ) {
super.installUI( c );
- applyStyle( FlatStylingSupport.getStyle( c ) );
+ installStyle();
}
@Override
@@ -68,18 +67,23 @@ public class FlatPopupMenuUI
protected void installListeners() {
super.installListeners();
- propertyChangeListener = FlatStylingSupport.createPropertyChangeListener( popupMenu, this::applyStyle, null );
- popupMenu.addPropertyChangeListener( FlatClientProperties.STYLE, propertyChangeListener );
+ propertyChangeListener = FlatStylingSupport.createPropertyChangeListener( popupMenu, this::installStyle, null );
+ popupMenu.addPropertyChangeListener( propertyChangeListener );
}
@Override
protected void uninstallListeners() {
super.uninstallListeners();
- popupMenu.removePropertyChangeListener( FlatClientProperties.STYLE, propertyChangeListener );
+ popupMenu.removePropertyChangeListener( propertyChangeListener );
propertyChangeListener = null;
}
+ /** @since 2 */
+ protected void installStyle() {
+ applyStyle( FlatStylingSupport.getResolvedStyle( popupMenu, "PopupMenu" ) );
+ }
+
/** @since 2 */
protected void applyStyle( Object style ) {
oldStyleValues = FlatStylingSupport.parseAndApply( oldStyleValues, style, this::applyStyleProperty );
diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatProgressBarUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatProgressBarUI.java
index bfae831a..9af3a538 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatProgressBarUI.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatProgressBarUI.java
@@ -78,7 +78,7 @@ public class FlatProgressBarUI
public void installUI( JComponent c ) {
super.installUI( c );
- applyStyle( FlatStylingSupport.getStyle( progressBar ) );
+ installStyle();
}
@Override
@@ -112,7 +112,8 @@ public class FlatProgressBarUI
break;
case STYLE:
- applyStyle( e.getNewValue() );
+ case STYLE_CLASS:
+ installStyle();
progressBar.revalidate();
progressBar.repaint();
break;
@@ -129,6 +130,11 @@ public class FlatProgressBarUI
propertyChangeListener = null;
}
+ /** @since 2 */
+ protected void installStyle() {
+ applyStyle( FlatStylingSupport.getResolvedStyle( progressBar, "ProgressBar" ) );
+ }
+
/** @since 2 */
protected void applyStyle( Object style ) {
oldStyleValues = FlatStylingSupport.parseAndApply( oldStyleValues, style, this::applyStyleProperty );
diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatRadioButtonMenuItemUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatRadioButtonMenuItemUI.java
index 0309ae13..5cab968e 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatRadioButtonMenuItemUI.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatRadioButtonMenuItemUI.java
@@ -72,7 +72,7 @@ public class FlatRadioButtonMenuItemUI
public void installUI( JComponent c ) {
super.installUI( c );
- applyStyle( FlatStylingSupport.getStyle( menuItem ) );
+ installStyle();
}
@Override
@@ -98,7 +98,12 @@ public class FlatRadioButtonMenuItemUI
@Override
protected PropertyChangeListener createPropertyChangeListener( JComponent c ) {
- return FlatStylingSupport.createPropertyChangeListener( c, this::applyStyle, super.createPropertyChangeListener( c ) );
+ return FlatStylingSupport.createPropertyChangeListener( c, this::installStyle, super.createPropertyChangeListener( c ) );
+ }
+
+ /** @since 2 */
+ protected void installStyle() {
+ applyStyle( FlatStylingSupport.getResolvedStyle( menuItem, "RadioButtonMenuItem" ) );
}
/** @since 2 */
diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatRadioButtonUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatRadioButtonUI.java
index fbe719b2..75be18d9 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatRadioButtonUI.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatRadioButtonUI.java
@@ -90,7 +90,7 @@ public class FlatRadioButtonUI
public void installUI( JComponent c ) {
super.installUI( c );
- applyStyle( (AbstractButton) c, FlatStylingSupport.getStyle( c ) );
+ installStyle( (AbstractButton) c );
}
@Override
@@ -134,19 +134,29 @@ public class FlatRadioButtonUI
protected void propertyChange( AbstractButton b, PropertyChangeEvent e ) {
switch( e.getPropertyName() ) {
case FlatClientProperties.STYLE:
- Object style = e.getNewValue();
- if( style != null && shared ) {
+ case FlatClientProperties.STYLE_CLASS:
+ if( shared && FlatStylingSupport.hasStyleProperty( b ) ) {
// unshare component UI if necessary
// updateUI() invokes applyStyle() from installUI()
b.updateUI();
} else
- applyStyle( b, style );
+ installStyle( b );
b.revalidate();
b.repaint();
break;
}
}
+ /** @since 2 */
+ protected void installStyle( AbstractButton b ) {
+ applyStyle( b, FlatStylingSupport.getResolvedStyle( b, getStyleType() ) );
+ }
+
+ /** @since 2 */
+ String getStyleType() {
+ return "RadioButton";
+ }
+
/** @since 2 */
protected void applyStyle( AbstractButton b, Object style ) {
oldStyleValues = FlatStylingSupport.parseAndApply( oldStyleValues, style,
diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatScrollBarUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatScrollBarUI.java
index 7e6f23d0..f2f32e40 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatScrollBarUI.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatScrollBarUI.java
@@ -115,7 +115,7 @@ public class FlatScrollBarUI
public void installUI( JComponent c ) {
super.installUI( c );
- applyStyle( FlatStylingSupport.getStyle( c ) );
+ installStyle();
}
@Override
@@ -199,7 +199,8 @@ public class FlatScrollBarUI
break;
case FlatClientProperties.STYLE:
- applyStyle( e.getNewValue() );
+ case FlatClientProperties.STYLE_CLASS:
+ installStyle();
scrollbar.revalidate();
scrollbar.repaint();
break;
@@ -220,6 +221,11 @@ public class FlatScrollBarUI
};
}
+ /** @since 2 */
+ protected void installStyle() {
+ applyStyle( FlatStylingSupport.getResolvedStyle( scrollbar, "ScrollBar" ) );
+ }
+
/** @since 2 */
protected void applyStyle( Object style ) {
oldStyleValues = FlatStylingSupport.parseAndApply( oldStyleValues, style, this::applyStyleProperty );
diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatScrollPaneUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatScrollPaneUI.java
index c7f65b65..8adb6c6a 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatScrollPaneUI.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatScrollPaneUI.java
@@ -87,7 +87,7 @@ public class FlatScrollPaneUI
int focusWidth = UIManager.getInt( "Component.focusWidth" );
LookAndFeel.installProperty( c, "opaque", focusWidth == 0 );
- applyStyle( FlatStylingSupport.getStyle( c ) );
+ installStyle();
MigLayoutVisualPadding.install( scrollpane );
}
@@ -287,7 +287,8 @@ public class FlatScrollPaneUI
break;
case FlatClientProperties.STYLE:
- applyStyle( e.getNewValue() );
+ case FlatClientProperties.STYLE_CLASS:
+ installStyle();
scrollpane.revalidate();
scrollpane.repaint();
break;
@@ -301,6 +302,11 @@ public class FlatScrollPaneUI
return handler;
}
+ /** @since 2 */
+ protected void installStyle() {
+ applyStyle( FlatStylingSupport.getResolvedStyle( scrollpane, "ScrollPane" ) );
+ }
+
/** @since 2 */
protected void applyStyle( Object style ) {
oldStyleValues = FlatStylingSupport.parseAndApply( oldStyleValues, style, this::applyStyleProperty );
diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatSeparatorUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatSeparatorUI.java
index ebcdfc14..b002b0e5 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatSeparatorUI.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatSeparatorUI.java
@@ -28,7 +28,6 @@ import javax.swing.JSeparator;
import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicSeparatorUI;
-import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
@@ -80,7 +79,7 @@ public class FlatSeparatorUI
public void installUI( JComponent c ) {
super.installUI( c );
- applyStyle( (JSeparator) c, FlatStylingSupport.getStyle( c ) );
+ installStyle( (JSeparator) c );
}
@Override
@@ -110,29 +109,39 @@ public class FlatSeparatorUI
super.installListeners( s );
propertyChangeListener = FlatStylingSupport.createPropertyChangeListener(
- s, style -> applyStyle( s, this, style ), null );
- s.addPropertyChangeListener( FlatClientProperties.STYLE, propertyChangeListener );
+ s, () -> stylePropertyChange( s ), null );
+ s.addPropertyChangeListener( propertyChangeListener );
}
@Override
protected void uninstallListeners( JSeparator s ) {
super.uninstallListeners( s );
- s.removePropertyChangeListener( FlatClientProperties.STYLE, propertyChangeListener );
+ s.removePropertyChangeListener( propertyChangeListener );
propertyChangeListener = null;
}
- private static void applyStyle( JSeparator s, FlatSeparatorUI ui, Object style ) {
- if( style != null && ui.shared ) {
+ private void stylePropertyChange( JSeparator s ) {
+ if( shared && FlatStylingSupport.hasStyleProperty( s ) ) {
// unshare component UI if necessary
// updateUI() invokes applyStyle() from installUI()
s.updateUI();
} else
- ui.applyStyle( s, style );
+ installStyle( s );
s.revalidate();
s.repaint();
}
+ /** @since 2 */
+ protected void installStyle( JSeparator s ) {
+ applyStyle( s, FlatStylingSupport.getResolvedStyle( s, getStyleType() ) );
+ }
+
+ /** @since 2 */
+ String getStyleType() {
+ return "Separator";
+ }
+
/** @since 2 */
protected void applyStyle( JSeparator s, Object style ) {
oldStyleValues = FlatStylingSupport.parseAndApply( oldStyleValues, style,
diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatSliderUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatSliderUI.java
index 79c09caa..bb65102b 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatSliderUI.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatSliderUI.java
@@ -121,7 +121,7 @@ public class FlatSliderUI
public void installUI( JComponent c ) {
super.installUI( c );
- applyStyle( FlatStylingSupport.getStyle( slider ) );
+ installStyle();
}
@Override
@@ -188,10 +188,15 @@ public class FlatSliderUI
@Override
protected PropertyChangeListener createPropertyChangeListener( JSlider slider ) {
- return FlatStylingSupport.createPropertyChangeListener( slider, this::applyStyle,
+ return FlatStylingSupport.createPropertyChangeListener( slider, this::installStyle,
super.createPropertyChangeListener( slider ) );
}
+ /** @since 2 */
+ protected void installStyle() {
+ applyStyle( FlatStylingSupport.getResolvedStyle( slider, "Slider" ) );
+ }
+
/** @since 2 */
protected void applyStyle( Object style ) {
oldStyleValues = FlatStylingSupport.parseAndApply( oldStyleValues, style, this::applyStyleProperty );
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 a0f87b5d..8819b32a 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
@@ -114,7 +114,7 @@ public class FlatSpinnerUI
public void installUI( JComponent c ) {
super.installUI( c );
- applyStyle( FlatStylingSupport.getStyle( spinner ) );
+ installStyle();
}
@Override
@@ -190,6 +190,11 @@ public class FlatSpinnerUI
return handler;
}
+ /** @since 2 */
+ protected void installStyle() {
+ applyStyle( FlatStylingSupport.getResolvedStyle( spinner, "Spinner" ) );
+ }
+
/** @since 2 */
protected void applyStyle( Object style ) {
oldStyleValues = FlatStylingSupport.parseAndApply( oldStyleValues, style, this::applyStyleProperty );
@@ -530,7 +535,8 @@ public class FlatSpinnerUI
break;
case FlatClientProperties.STYLE:
- applyStyle( e.getNewValue() );
+ case FlatClientProperties.STYLE_CLASS:
+ installStyle();
spinner.revalidate();
spinner.repaint();
break;
diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatSplitPaneUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatSplitPaneUI.java
index 667cca3b..6d537a72 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatSplitPaneUI.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatSplitPaneUI.java
@@ -34,7 +34,6 @@ import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicSplitPaneDivider;
import javax.swing.plaf.basic.BasicSplitPaneUI;
-import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
import com.formdev.flatlaf.ui.FlatStylingSupport.UnknownStyleException;
@@ -90,7 +89,7 @@ public class FlatSplitPaneUI
public void installUI( JComponent c ) {
super.installUI( c );
- applyStyle( FlatStylingSupport.getStyle( splitPane ) );
+ installStyle();
}
@Override
@@ -121,15 +120,15 @@ public class FlatSplitPaneUI
protected void installListeners() {
super.installListeners();
- propertyChangeListener = FlatStylingSupport.createPropertyChangeListener( splitPane, this::applyStyle, null );
- splitPane.addPropertyChangeListener( FlatClientProperties.STYLE, propertyChangeListener );
+ propertyChangeListener = FlatStylingSupport.createPropertyChangeListener( splitPane, this::installStyle, null );
+ splitPane.addPropertyChangeListener( propertyChangeListener );
}
@Override
protected void uninstallListeners() {
super.uninstallListeners();
- splitPane.removePropertyChangeListener( FlatClientProperties.STYLE, propertyChangeListener );
+ splitPane.removePropertyChangeListener( propertyChangeListener );
propertyChangeListener = null;
}
@@ -138,6 +137,11 @@ public class FlatSplitPaneUI
return new FlatSplitPaneDivider( this );
}
+ /** @since 2 */
+ protected void installStyle() {
+ applyStyle( FlatStylingSupport.getResolvedStyle( splitPane, "SplitPane" ) );
+ }
+
/** @since 2 */
protected void applyStyle( Object style ) {
oldStyleValues = FlatStylingSupport.parseAndApply( oldStyleValues, style, this::applyStyleProperty );
diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatStylingSupport.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatStylingSupport.java
index 6afeb8d8..49ab18e3 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatStylingSupport.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatStylingSupport.java
@@ -26,10 +26,10 @@ import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.LinkedHashMap;
+import java.util.List;
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;
import javax.swing.Icon;
import javax.swing.JComponent;
@@ -73,6 +73,150 @@ public class FlatStylingSupport
Map> getStyleableInfos();
}
+
+ /**
+ * Returns the style specified in client property {@link FlatClientProperties#STYLE}.
+ */
+ public static Object getStyle( JComponent c ) {
+ return c.getClientProperty( FlatClientProperties.STYLE );
+ }
+
+ /**
+ * Returns the style class(es) specified in client property {@link FlatClientProperties#STYLE_CLASS}.
+ */
+ public static Object getStyleClass( JComponent c ) {
+ return c.getClientProperty( FlatClientProperties.STYLE_CLASS );
+ }
+
+ static boolean hasStyleProperty( JComponent c ) {
+ return getStyle( c ) != null || getStyleClass( c ) != null;
+ }
+
+ public static Object getResolvedStyle( JComponent c, String type ) {
+ Object style = getStyle( c );
+ Object styleClass = getStyleClass( c );
+ Object styleForClasses = getStyleForClasses( styleClass, type );
+ return joinStyles( styleForClasses, style );
+ }
+
+ /**
+ * Returns the styles for the given style class(es) and the given type.
+ *
+ * The style rules must be defined in UI defaults either as strings (in CSS syntax)
+ * or as {@link java.util.Map}<String, Object> (with binary values).
+ * The key must be in syntax: {@code [style]type.styleClass}, where the type is optional.
+ * E.g. in FlatLaf properties file:
+ *
{@code
+ * [style]Button.primary = borderColor: #08f; background: #08f; foreground: #fff
+ * [style].secondary = borderColor: #0f8; background: #0f8
+ * }
+ * or in Java code:
+ * {@code
+ * UIManager.put( "[style]Button.primary", "borderColor: #08f; background: #08f; foreground: #fff" );
+ * UIManager.put( "[style].secondary", "borderColor: #0f8; background: #0f8" );
+ * }
+ * The rule "Button.primary" can be applied to buttons only.
+ * The rule ".secondary" can be applied to any component.
+ *
+ * To have similar behaviour as in CSS, this method first gets the rule without type,
+ * then the rule with type and concatenates both rules.
+ * E.g. invoking this method with parameters styleClass="foo" and type="Button" does following:
+ *
{@code
+ * return joinStyles(
+ * UIManager.get( "[style].foo" ),
+ * UIManager.get( "[style]Button.foo" ) );
+ * }
+ *
+ * @param styleClass the style class(es) either as string (single class)
+ * or as {@code String[]} or {@link java.util.List}<String> (multiple classes)
+ * @param type the type of the component
+ * @return the styles
+ */
+ public static Object getStyleForClasses( Object styleClass, String type ) {
+ if( styleClass == null )
+ return null;
+
+ if( styleClass instanceof String )
+ return getStyleForClass( (String) styleClass, type );
+ else if( styleClass instanceof String[] ) {
+ Object style = null;
+ for( String cls : (String[]) styleClass )
+ style = joinStyles( style, getStyleForClass( cls, type ) );
+ return style;
+ } else if( styleClass instanceof List> ) {
+ Object style = null;
+ for( Object cls : (List>) styleClass )
+ style = joinStyles( style, getStyleForClass( (String) cls, type ) );
+ return style;
+ } else
+ return null;
+ }
+
+ private static Object getStyleForClass( String styleClass, String type ) {
+ return joinStyles(
+ UIManager.get( "[style]." + styleClass ),
+ UIManager.get( "[style]" + type + '.' + styleClass ) );
+ }
+
+ /**
+ * Joins two styles. They can be either strings (in CSS syntax)
+ * or {@link java.util.Map}<String, Object> (with binary values).
+ *
+ * If both styles are strings, then a joined string is returned.
+ * If both styles are maps, then a joined map is returned.
+ * If one style is a map and the other style a string, then the string
+ * is parsed (using {@link #parse(String)}) to a map and a joined map is returned.
+ *
+ * @param style1 first style as string or map, or {@code null}
+ * @param style2 second style as string or map, or {@code null}
+ * @return new joined style
+ */
+ @SuppressWarnings( "unchecked" )
+ public static Object joinStyles( Object style1, Object style2 ) {
+ if( style1 == null )
+ return style2;
+ if( style2 == null )
+ return style1;
+
+ // join two strings
+ if( style1 instanceof String && style2 instanceof String )
+ return style1 + "; " + style2;
+
+ // convert first style to map
+ Map map1 = (style1 instanceof String)
+ ? parse( (String) style1 )
+ : (Map) style1;
+ if( map1 == null )
+ return style2;
+
+ // convert second style to map
+ Map map2 = (style2 instanceof String)
+ ? parse( (String) style2 )
+ : (Map) style2;
+ if( map2 == null )
+ return style1;
+
+ // join two maps
+ Map map = new HashMap<>( map1 );
+ map.putAll( map2 );
+ return map;
+ }
+
+ /**
+ * Concatenates two styles in CSS syntax.
+ *
+ * @param style1 first style, or {@code null}
+ * @param style2 second style, or {@code null}
+ * @return concatenation of the two styles separated by a semicolon
+ */
+ public static String concatStyles( String style1, String style2 ) {
+ if( style1 == null )
+ return style2;
+ if( style2 == null )
+ return style1;
+ return style1 + "; " + style2;
+ }
+
/**
* Parses styles in CSS syntax ("key1: value1; key2: value2; ..."),
* converts the value strings into binary and invokes the given function
@@ -408,21 +552,20 @@ public class FlatStylingSupport
}
}
- public static Object getStyle( JComponent c ) {
- return c.getClientProperty( FlatClientProperties.STYLE );
- }
-
static PropertyChangeListener createPropertyChangeListener( JComponent c,
- Consumer applyStyle, PropertyChangeListener superListener )
+ Runnable installStyle, PropertyChangeListener superListener )
{
return e -> {
if( superListener != null )
superListener.propertyChange( e );
- if( FlatClientProperties.STYLE.equals( e.getPropertyName() ) ) {
- applyStyle.accept( e.getNewValue() );
- c.revalidate();
- c.repaint();
+ switch( e.getPropertyName() ) {
+ case FlatClientProperties.STYLE:
+ case FlatClientProperties.STYLE_CLASS:
+ installStyle.run();
+ c.revalidate();
+ c.repaint();
+ break;
}
};
}
diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTabbedPaneUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTabbedPaneUI.java
index f310f997..67d900be 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTabbedPaneUI.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTabbedPaneUI.java
@@ -269,7 +269,7 @@ public class FlatTabbedPaneUI
super.installUI( c );
- applyStyle( FlatStylingSupport.getStyle( c ) );
+ installStyle();
}
@Override
@@ -572,6 +572,11 @@ public class FlatTabbedPaneUI
return new FlatScrollableTabButton( direction );
}
+ /** @since 2 */
+ protected void installStyle() {
+ applyStyle( FlatStylingSupport.getResolvedStyle( tabPane, "TabbedPane" ) );
+ }
+
/** @since 2 */
protected void applyStyle( Object style ) {
oldStyleValues = FlatStylingSupport.parseAndApply( oldStyleValues, style, this::applyStyleProperty );
@@ -2439,7 +2444,8 @@ public class FlatTabbedPaneUI
break;
case STYLE:
- applyStyle( e.getNewValue() );
+ case STYLE_CLASS:
+ installStyle();
tabPane.revalidate();
tabPane.repaint();
break;
diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTableHeaderUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTableHeaderUI.java
index f8540966..0c0904b5 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTableHeaderUI.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTableHeaderUI.java
@@ -41,7 +41,6 @@ import javax.swing.plaf.UIResource;
import javax.swing.plaf.basic.BasicTableHeaderUI;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumnModel;
-import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
import com.formdev.flatlaf.util.UIScale;
@@ -104,7 +103,7 @@ public class FlatTableHeaderUI
public void installUI( JComponent c ) {
super.installUI( c );
- applyStyle( FlatStylingSupport.getStyle( c ) );
+ installStyle();
}
@Override
@@ -129,18 +128,23 @@ public class FlatTableHeaderUI
protected void installListeners() {
super.installListeners();
- propertyChangeListener = FlatStylingSupport.createPropertyChangeListener( header, this::applyStyle, null );
- header.addPropertyChangeListener( FlatClientProperties.STYLE, propertyChangeListener );
+ propertyChangeListener = FlatStylingSupport.createPropertyChangeListener( header, this::installStyle, null );
+ header.addPropertyChangeListener( propertyChangeListener );
}
@Override
protected void uninstallListeners() {
super.uninstallListeners();
- header.removePropertyChangeListener( FlatClientProperties.STYLE, propertyChangeListener );
+ header.removePropertyChangeListener( propertyChangeListener );
propertyChangeListener = null;
}
+ /** @since 2 */
+ protected void installStyle() {
+ applyStyle( FlatStylingSupport.getResolvedStyle( header, "TableHeader" ) );
+ }
+
/** @since 2 */
protected void applyStyle( Object style ) {
oldStyleValues = FlatStylingSupport.parseAndApply( oldStyleValues, style, this::applyStyleProperty );
diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTableUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTableUI.java
index 86bc82a0..b3df21f3 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTableUI.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTableUI.java
@@ -126,7 +126,7 @@ public class FlatTableUI
public void installUI( JComponent c ) {
super.installUI( c );
- applyStyle( FlatStylingSupport.getStyle( c ) );
+ installStyle();
}
@Override
@@ -197,7 +197,8 @@ public class FlatTableUI
break;
case FlatClientProperties.STYLE:
- applyStyle( e.getNewValue() );
+ case FlatClientProperties.STYLE_CLASS:
+ installStyle();
table.revalidate();
table.repaint();
break;
@@ -235,6 +236,11 @@ public class FlatTableUI
};
}
+ /** @since 2 */
+ protected void installStyle() {
+ applyStyle( FlatStylingSupport.getResolvedStyle( table, "Table" ) );
+ }
+
/** @since 2 */
protected void applyStyle( Object style ) {
Color oldSelectionBackground = selectionBackground;
diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTextAreaUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTextAreaUI.java
index dff2f9d1..244757e3 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTextAreaUI.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTextAreaUI.java
@@ -86,7 +86,7 @@ public class FlatTextAreaUI
public void installUI( JComponent c ) {
super.installUI( c );
- applyStyle( FlatStylingSupport.getStyle( c ) );
+ installStyle();
}
@Override
@@ -143,7 +143,12 @@ public class FlatTextAreaUI
updateBackground();
super.propertyChange( e );
- FlatEditorPaneUI.propertyChange( getComponent(), e, this::applyStyle );
+ FlatEditorPaneUI.propertyChange( getComponent(), e, this::installStyle );
+ }
+
+ /** @since 2 */
+ protected void installStyle() {
+ applyStyle( FlatStylingSupport.getResolvedStyle( getComponent(), "TextArea" ) );
}
/** @since 2 */
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 51297da0..2e676135 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
@@ -114,7 +114,7 @@ public class FlatTextFieldUI
leadingIcon = clientProperty( c, TEXT_FIELD_LEADING_ICON, null, Icon.class );
trailingIcon = clientProperty( c, TEXT_FIELD_TRAILING_ICON, null, Icon.class );
- applyStyle( FlatStylingSupport.getStyle( c ) );
+ installStyle();
}
@Override
@@ -209,7 +209,8 @@ public class FlatTextFieldUI
break;
case STYLE:
- applyStyle( e.getNewValue() );
+ case STYLE_CLASS:
+ installStyle();
c.revalidate();
c.repaint();
break;
@@ -226,6 +227,16 @@ public class FlatTextFieldUI
}
}
+ /** @since 2 */
+ protected void installStyle() {
+ applyStyle( FlatStylingSupport.getResolvedStyle( getComponent(), getStyleType() ) );
+ }
+
+ /** @since 2 */
+ String getStyleType() {
+ return "TextField";
+ }
+
/** @since 2 */
protected void applyStyle( Object style ) {
oldDisabledBackground = disabledBackground;
diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTextPaneUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTextPaneUI.java
index de5b870c..5aa3b6a1 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTextPaneUI.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTextPaneUI.java
@@ -87,7 +87,7 @@ public class FlatTextPaneUI
public void installUI( JComponent c ) {
super.installUI( c );
- applyStyle( FlatStylingSupport.getStyle( c ) );
+ installStyle();
}
@Override
@@ -151,7 +151,12 @@ public class FlatTextPaneUI
updateBackground();
super.propertyChange( e );
- FlatEditorPaneUI.propertyChange( getComponent(), e, this::applyStyle );
+ FlatEditorPaneUI.propertyChange( getComponent(), e, this::installStyle );
+ }
+
+ /** @since 2 */
+ protected void installStyle() {
+ applyStyle( FlatStylingSupport.getResolvedStyle( getComponent(), "TextPane" ) );
}
/** @since 2 */
diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatToggleButtonUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatToggleButtonUI.java
index a029e740..89e1492f 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatToggleButtonUI.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatToggleButtonUI.java
@@ -96,6 +96,11 @@ public class FlatToggleButtonUI
super( shared );
}
+ @Override
+ String getStyleType() {
+ return "ToggleButton";
+ }
+
@Override
protected String getPropertyPrefix() {
return "ToggleButton.";
diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatToolBarSeparatorUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatToolBarSeparatorUI.java
index 0978cc99..865fe3a2 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatToolBarSeparatorUI.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatToolBarSeparatorUI.java
@@ -31,7 +31,6 @@ import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicToolBarSeparatorUI;
-import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
@@ -74,7 +73,7 @@ public class FlatToolBarSeparatorUI
public void installUI( JComponent c ) {
super.installUI( c );
- applyStyle( FlatStylingSupport.getStyle( c ) );
+ installStyle( (JSeparator) c );
}
@Override
@@ -106,29 +105,34 @@ public class FlatToolBarSeparatorUI
super.installListeners( s );
propertyChangeListener = FlatStylingSupport.createPropertyChangeListener(
- s, style -> applyStyle( s, this, style ), null );
- s.addPropertyChangeListener( FlatClientProperties.STYLE, propertyChangeListener );
+ s, () -> stylePropertyChange( s ), null );
+ s.addPropertyChangeListener( propertyChangeListener );
}
@Override
protected void uninstallListeners( JSeparator s ) {
super.uninstallListeners( s );
- s.removePropertyChangeListener( FlatClientProperties.STYLE, propertyChangeListener );
+ s.removePropertyChangeListener( propertyChangeListener );
propertyChangeListener = null;
}
- private static void applyStyle( JSeparator s, FlatToolBarSeparatorUI ui, Object style ) {
- if( style != null && ui.shared ) {
+ private void stylePropertyChange( JSeparator s ) {
+ if( shared && FlatStylingSupport.hasStyleProperty( s ) ) {
// unshare component UI if necessary
// updateUI() invokes applyStyle() from installUI()
s.updateUI();
} else
- ui.applyStyle( style );
+ installStyle( s );
s.revalidate();
s.repaint();
}
+ /** @since 2 */
+ protected void installStyle( JSeparator s ) {
+ applyStyle( FlatStylingSupport.getResolvedStyle( s, "ToolBarSeparator" ) );
+ }
+
/** @since 2 */
protected void applyStyle( Object style ) {
oldStyleValues = FlatStylingSupport.parseAndApply( oldStyleValues, style, this::applyStyleProperty );
diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatToolBarUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatToolBarUI.java
index f863e6c4..291bd0f4 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatToolBarUI.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatToolBarUI.java
@@ -83,7 +83,7 @@ public class FlatToolBarUI
if( !focusableButtons )
setButtonsFocusable( false );
- applyStyle( FlatStylingSupport.getStyle( c ) );
+ installStyle();
}
@Override
@@ -133,7 +133,12 @@ public class FlatToolBarUI
@Override
protected PropertyChangeListener createPropertyListener() {
- return FlatStylingSupport.createPropertyChangeListener( toolBar, this::applyStyle, super.createPropertyListener() );
+ return FlatStylingSupport.createPropertyChangeListener( toolBar, this::installStyle, super.createPropertyListener() );
+ }
+
+ /** @since 2 */
+ protected void installStyle() {
+ applyStyle( FlatStylingSupport.getResolvedStyle( toolBar, "ToolBar" ) );
}
/** @since 2 */
diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTreeUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTreeUI.java
index 68d9b842..531b732e 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTreeUI.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTreeUI.java
@@ -156,7 +156,7 @@ public class FlatTreeUI
public void installUI( JComponent c ) {
super.installUI( c );
- applyStyle( FlatStylingSupport.getStyle( c ) );
+ installStyle();
}
@Override
@@ -271,7 +271,8 @@ public class FlatTreeUI
break;
case STYLE:
- applyStyle( e.getNewValue() );
+ case STYLE_CLASS:
+ installStyle();
tree.revalidate();
tree.repaint();
break;
@@ -309,6 +310,11 @@ public class FlatTreeUI
return bounds;
}
+ /** @since 2 */
+ protected void installStyle() {
+ applyStyle( FlatStylingSupport.getResolvedStyle( tree, "Tree" ) );
+ }
+
/** @since 2 */
protected void applyStyle( Object style ) {
oldStyleValues = FlatStylingSupport.parseAndApply( oldStyleValues, style, this::applyStyleProperty );
diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatUIUtils.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatUIUtils.java
index 795fe2c7..fc3777a7 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatUIUtils.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatUIUtils.java
@@ -370,14 +370,16 @@ public class FlatUIUtils
* an (optional) component border
* the (optional) component background
*
+ *
+ *
* Each part is painted only if the corresponding part color is not {@code null}.
* The parts are painted in this order:
- *
*
* background
* focus border
* border
*
+ *
*
* Background :
* The bounds of the filled round rectangle are
@@ -939,7 +941,7 @@ debug*/
* with other components. This is only possible if it does not have styles.
*/
public static boolean canUseSharedUI( JComponent c ) {
- return FlatStylingSupport.getStyle( c ) == null;
+ return !FlatStylingSupport.hasStyleProperty( c );
}
//---- class RepaintFocusListener -----------------------------------------
diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/MigLayoutVisualPadding.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/MigLayoutVisualPadding.java
index 7df37989..89389ab9 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/MigLayoutVisualPadding.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/MigLayoutVisualPadding.java
@@ -81,7 +81,7 @@ public class MigLayoutVisualPadding
return new Insets( focusWidth, focusWidth, focusWidth, focusWidth );
} else
return null;
- }, "border", FlatClientProperties.STYLE );
+ }, "border", FlatClientProperties.STYLE, FlatClientProperties.STYLE_CLASS );
}
/**
@@ -100,7 +100,7 @@ public class MigLayoutVisualPadding
c.addPropertyChangeListener( (FlatMigListener) e -> {
String propertyName = e.getPropertyName();
for( String name : propertyNames ) {
- if( name == propertyName ) {
+ if( name.equals( propertyName ) ) {
setVisualPadding( c, getPaddingFunction.apply( c ) );
break;
}
diff --git a/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleClasses.java b/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleClasses.java
new file mode 100644
index 00000000..d96036f1
--- /dev/null
+++ b/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleClasses.java
@@ -0,0 +1,448 @@
+/*
+ * Copyright 2021 FormDev Software GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.formdev.flatlaf.ui;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import java.awt.Color;
+import java.awt.Dimension;
+import javax.swing.*;
+import javax.swing.table.JTableHeader;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import com.formdev.flatlaf.FlatClientProperties;
+import com.formdev.flatlaf.FlatSystemProperties;
+
+/**
+ * @author Karl Tauber
+ */
+public class TestFlatStyleClasses
+{
+ private static final String BUTTON_PRIMARY = "borderColor: #08f; background: #08f; foreground: #fff";
+ private static final String SECONDARY = "borderColor: #0f8; background: #0f8";
+ private static final String TOGGLE_BUTTON_SECONDARY = "selectedBackground: #f00";
+ private static final String BACKGROUND = "background: #f0f";
+
+ @BeforeAll
+ static void setup() {
+ System.setProperty( FlatSystemProperties.UI_SCALE_ENABLED, "false" );
+ TestUtils.setup( false );
+
+ UIManager.put( "[style]Button.primary", BUTTON_PRIMARY );
+ UIManager.put( "[style].secondary", SECONDARY );
+ UIManager.put( "[style]ToggleButton.secondary", TOGGLE_BUTTON_SECONDARY );
+ UIManager.put( "[style].test", BACKGROUND );
+
+ UIManager.put( "[style]Button.test", "foreground: #000001" );
+ UIManager.put( "[style]CheckBox.test", "foreground: #000002" );
+ UIManager.put( "[style]ComboBox.test", "foreground: #000003" );
+ UIManager.put( "[style]EditorPane.test", "foreground: #000004" );
+ UIManager.put( "[style]FormattedTextField.test", "foreground: #000005" );
+ UIManager.put( "[style]InternalFrame.test", "foreground: #000006" );
+ UIManager.put( "[style]Label.test", "foreground: #000007" );
+ UIManager.put( "[style]List.test", "foreground: #000008" );
+ UIManager.put( "[style]MenuBar.test", "foreground: #000009" );
+ UIManager.put( "[style]Menu.test", "foreground: #000010" );
+ UIManager.put( "[style]MenuItem.test", "foreground: #000011" );
+ UIManager.put( "[style]CheckBoxMenuItem.test", "foreground: #000012" );
+ UIManager.put( "[style]RadioButtonMenuItem.test", "foreground: #000013" );
+ UIManager.put( "[style]PasswordField.test", "foreground: #000014" );
+ UIManager.put( "[style]PopupMenu.test", "foreground: #000015" );
+ UIManager.put( "[style]PopupMenuSeparator.test", "foreground: #000016" );
+ UIManager.put( "[style]ProgressBar.test", "foreground: #000017" );
+ UIManager.put( "[style]RadioButton.test", "foreground: #000018" );
+ UIManager.put( "[style]ScrollBar.test", "foreground: #000019" );
+ UIManager.put( "[style]ScrollPane.test", "foreground: #000020" );
+ UIManager.put( "[style]Separator.test", "foreground: #000021" );
+ UIManager.put( "[style]Slider.test", "foreground: #000022" );
+ UIManager.put( "[style]Spinner.test", "foreground: #000023" );
+ UIManager.put( "[style]SplitPane.test", "foreground: #000024" );
+ UIManager.put( "[style]TabbedPane.test", "foreground: #000025" );
+ UIManager.put( "[style]Table.test", "foreground: #000026" );
+ UIManager.put( "[style]TableHeader.test", "foreground: #000027" );
+ UIManager.put( "[style]TextArea.test", "foreground: #000028" );
+ UIManager.put( "[style]TextField.test", "foreground: #000029" );
+ UIManager.put( "[style]TextPane.test", "foreground: #000030" );
+ UIManager.put( "[style]ToggleButton.test", "foreground: #000031" );
+ UIManager.put( "[style]ToolBar.test", "foreground: #000032" );
+ UIManager.put( "[style]Tree.test", "foreground: #000033" );
+
+ // for shared UIs
+ UIManager.put( "[style]Button.test2", "foreground: #000100" );
+ UIManager.put( "[style]CheckBox.test2", "foreground: #000200" );
+ UIManager.put( "[style]Label.test2", "foreground: #000700" );
+ UIManager.put( "[style]PopupMenuSeparator.test2", "foreground: #001600" );
+ UIManager.put( "[style]RadioButton.test2", "foreground: #001800" );
+ UIManager.put( "[style]Separator.test2", "foreground: #002100" );
+ UIManager.put( "[style]ToggleButton.test2", "foreground: #003100" );
+
+ // JToolBar.Separator
+ UIManager.put( "[style]ToolBarSeparator.toolbar-separator-test", "separatorWidth: 21" );
+ UIManager.put( "[style]ToolBarSeparator.toolbar-separator-test2", "separatorWidth: 31" );
+ }
+
+ @AfterAll
+ static void cleanup() {
+ TestUtils.cleanup();
+ System.clearProperty( FlatSystemProperties.UI_SCALE_ENABLED );
+ }
+
+ @Test
+ void styleForClass() {
+ assertEquals( null, FlatStylingSupport.getStyleForClasses( "foo", "Button" ) );
+
+ assertEquals( BUTTON_PRIMARY, FlatStylingSupport.getStyleForClasses( "primary", "Button" ) );
+ assertEquals( SECONDARY, FlatStylingSupport.getStyleForClasses( "secondary", "Button" ) );
+
+ assertEquals(
+ FlatStylingSupport.concatStyles( SECONDARY, TOGGLE_BUTTON_SECONDARY ),
+ FlatStylingSupport.getStyleForClasses( "secondary", "ToggleButton" ) );
+
+ assertEquals(
+ FlatStylingSupport.concatStyles( BUTTON_PRIMARY, SECONDARY ),
+ FlatStylingSupport.getStyleForClasses( new String[] { "primary", "secondary" }, "Button" ) );
+ assertEquals(
+ FlatStylingSupport.concatStyles( SECONDARY, BUTTON_PRIMARY ),
+ FlatStylingSupport.getStyleForClasses( new String[] { "secondary", "primary" }, "Button" ) );
+ }
+
+ @Test
+ void apply1() {
+ JButton c = new JButton();
+ c.putClientProperty( FlatClientProperties.STYLE_CLASS, "primary" );
+
+ assertEquals( new Color( 0x0088ff ), c.getBackground() );
+ assertEquals( Color.white, c.getForeground() );
+ }
+
+ @Test
+ void apply2() {
+ JButton c = new JButton();
+ c.putClientProperty( FlatClientProperties.STYLE_CLASS, new String[] { "primary", "secondary" } );
+
+ assertEquals( new Color( 0x00ff88 ), c.getBackground() );
+ assertEquals( Color.white, c.getForeground() );
+ }
+
+ @Test
+ void apply3() {
+ JButton c = new JButton();
+ c.putClientProperty( FlatClientProperties.STYLE_CLASS, new String[] { "secondary", "primary" } );
+
+ assertEquals( new Color( 0x0088ff ), c.getBackground() );
+ assertEquals( Color.white, c.getForeground() );
+ }
+
+ //---- components ---------------------------------------------------------
+
+ @Test
+ void button() {
+ JButton c = new JButton();
+ c.putClientProperty( FlatClientProperties.STYLE_CLASS, "test" );
+ assertEquals( Color.magenta, c.getBackground() );
+ assertEquals( new Color( 0x000001 ), c.getForeground() );
+
+ c.putClientProperty( FlatClientProperties.STYLE_CLASS, "test2" );
+ assertEquals( new Color( 0x000100 ), c.getForeground() );
+ }
+
+ @Test
+ void checkBox() {
+ JCheckBox c = new JCheckBox();
+ c.putClientProperty( FlatClientProperties.STYLE_CLASS, "test" );
+ assertEquals( Color.magenta, c.getBackground() );
+ assertEquals( new Color( 0x000002 ), c.getForeground() );
+
+ c.putClientProperty( FlatClientProperties.STYLE_CLASS, "test2" );
+ assertEquals( new Color( 0x000200 ), c.getForeground() );
+ }
+
+ @Test
+ void comboBox() {
+ JComboBox c = new JComboBox<>();
+ c.putClientProperty( FlatClientProperties.STYLE_CLASS, "test" );
+ assertEquals( Color.magenta, c.getBackground() );
+ assertEquals( new Color( 0x000003 ), c.getForeground() );
+ }
+
+ @Test
+ void editorPane() {
+ JEditorPane c = new JEditorPane();
+ c.putClientProperty( FlatClientProperties.STYLE_CLASS, "test" );
+ assertEquals( Color.magenta, c.getBackground() );
+ assertEquals( new Color( 0x000004 ), c.getForeground() );
+ }
+
+ @Test
+ void formattedTextField() {
+ JFormattedTextField c = new JFormattedTextField();
+ c.putClientProperty( FlatClientProperties.STYLE_CLASS, "test" );
+ assertEquals( Color.magenta, c.getBackground() );
+ assertEquals( new Color( 0x000005 ), c.getForeground() );
+ }
+
+ @Test
+ void internalFrame() {
+ JInternalFrame c = new JInternalFrame();
+ c.putClientProperty( FlatClientProperties.STYLE_CLASS, "test" );
+ assertEquals( Color.magenta, c.getBackground() );
+ assertEquals( new Color( 0x000006 ), c.getForeground() );
+ }
+
+ @Test
+ void label() {
+ JLabel c = new JLabel();
+ c.putClientProperty( FlatClientProperties.STYLE_CLASS, "test" );
+ assertEquals( Color.magenta, c.getBackground() );
+ assertEquals( new Color( 0x000007 ), c.getForeground() );
+
+ c.putClientProperty( FlatClientProperties.STYLE_CLASS, "test2" );
+ assertEquals( new Color( 0x000700 ), c.getForeground() );
+ }
+
+ @Test
+ void list() {
+ JList c = new JList<>();
+ c.putClientProperty( FlatClientProperties.STYLE_CLASS, "test" );
+ assertEquals( Color.magenta, c.getBackground() );
+ assertEquals( new Color( 0x000008 ), c.getForeground() );
+ }
+
+ @Test
+ void menuBar() {
+ JMenuBar c = new JMenuBar();
+ c.putClientProperty( FlatClientProperties.STYLE_CLASS, "test" );
+ assertEquals( Color.magenta, c.getBackground() );
+ assertEquals( new Color( 0x000009 ), c.getForeground() );
+ }
+
+ @Test
+ void menu() {
+ JMenu c = new JMenu();
+ c.putClientProperty( FlatClientProperties.STYLE_CLASS, "test" );
+ assertEquals( Color.magenta, c.getBackground() );
+ assertEquals( new Color( 0x000010 ), c.getForeground() );
+ }
+
+ @Test
+ void menuItem() {
+ JMenuItem c = new JMenuItem();
+ c.putClientProperty( FlatClientProperties.STYLE_CLASS, "test" );
+ assertEquals( Color.magenta, c.getBackground() );
+ assertEquals( new Color( 0x000011 ), c.getForeground() );
+ }
+
+ @Test
+ void checkBoxMenuItem() {
+ JCheckBoxMenuItem c = new JCheckBoxMenuItem();
+ c.putClientProperty( FlatClientProperties.STYLE_CLASS, "test" );
+ assertEquals( Color.magenta, c.getBackground() );
+ assertEquals( new Color( 0x000012 ), c.getForeground() );
+ }
+
+ @Test
+ void radioButtonMenuItem() {
+ JRadioButtonMenuItem c = new JRadioButtonMenuItem();
+ c.putClientProperty( FlatClientProperties.STYLE_CLASS, "test" );
+ assertEquals( Color.magenta, c.getBackground() );
+ assertEquals( new Color( 0x000013 ), c.getForeground() );
+ }
+
+ @Test
+ void passwordField() {
+ JPasswordField c = new JPasswordField();
+ c.putClientProperty( FlatClientProperties.STYLE_CLASS, "test" );
+ assertEquals( Color.magenta, c.getBackground() );
+ assertEquals( new Color( 0x000014 ), c.getForeground() );
+ }
+
+ @Test
+ void popupMenu() {
+ JPopupMenu c = new JPopupMenu();
+ c.putClientProperty( FlatClientProperties.STYLE_CLASS, "test" );
+ assertEquals( Color.magenta, c.getBackground() );
+ assertEquals( new Color( 0x000015 ), c.getForeground() );
+ }
+
+ @Test
+ void popupMenuSeparator() {
+ JPopupMenu.Separator c = new JPopupMenu.Separator();
+ c.putClientProperty( FlatClientProperties.STYLE_CLASS, "test" );
+ assertEquals( Color.magenta, c.getBackground() );
+ assertEquals( new Color( 0x000016 ), c.getForeground() );
+
+ c.putClientProperty( FlatClientProperties.STYLE_CLASS, "test2" );
+ assertEquals( new Color( 0x001600 ), c.getForeground() );
+ }
+
+ @Test
+ void progressBar() {
+ JProgressBar c = new JProgressBar();
+ c.putClientProperty( FlatClientProperties.STYLE_CLASS, "test" );
+ assertEquals( Color.magenta, c.getBackground() );
+ assertEquals( new Color( 0x000017 ), c.getForeground() );
+ }
+
+ @Test
+ void radioButton() {
+ JRadioButton c = new JRadioButton();
+ c.putClientProperty( FlatClientProperties.STYLE_CLASS, "test" );
+ assertEquals( Color.magenta, c.getBackground() );
+ assertEquals( new Color( 0x000018 ), c.getForeground() );
+
+ c.putClientProperty( FlatClientProperties.STYLE_CLASS, "test2" );
+ assertEquals( new Color( 0x001800 ), c.getForeground() );
+ }
+
+ @Test
+ void scrollBar() {
+ JScrollBar c = new JScrollBar();
+ c.putClientProperty( FlatClientProperties.STYLE_CLASS, "test" );
+ assertEquals( Color.magenta, c.getBackground() );
+ assertEquals( new Color( 0x000019 ), c.getForeground() );
+ }
+
+ @Test
+ void scrollPane() {
+ JScrollPane c = new JScrollPane();
+ c.putClientProperty( FlatClientProperties.STYLE_CLASS, "test" );
+ assertEquals( Color.magenta, c.getBackground() );
+ assertEquals( new Color( 0x000020 ), c.getForeground() );
+ }
+
+ @Test
+ void separator() {
+ JSeparator c = new JSeparator();
+ c.putClientProperty( FlatClientProperties.STYLE_CLASS, "test" );
+ assertEquals( Color.magenta, c.getBackground() );
+ assertEquals( new Color( 0x000021 ), c.getForeground() );
+
+ c.putClientProperty( FlatClientProperties.STYLE_CLASS, "test2" );
+ assertEquals( new Color( 0x002100 ), c.getForeground() );
+ }
+
+ @Test
+ void slider() {
+ JSlider c = new JSlider();
+ c.putClientProperty( FlatClientProperties.STYLE_CLASS, "test" );
+ assertEquals( Color.magenta, c.getBackground() );
+ assertEquals( new Color( 0x000022 ), c.getForeground() );
+ }
+
+ @Test
+ void spinner() {
+ JSpinner c = new JSpinner();
+ c.putClientProperty( FlatClientProperties.STYLE_CLASS, "test" );
+ assertEquals( Color.magenta, c.getBackground() );
+ assertEquals( new Color( 0x000023 ), c.getForeground() );
+ }
+
+ @Test
+ void splitPane() {
+ JSplitPane c = new JSplitPane();
+ c.putClientProperty( FlatClientProperties.STYLE_CLASS, "test" );
+ assertEquals( Color.magenta, c.getBackground() );
+ assertEquals( new Color( 0x000024 ), c.getForeground() );
+ }
+
+ @Test
+ void tabbedPane() {
+ JTabbedPane c = new JTabbedPane();
+ c.putClientProperty( FlatClientProperties.STYLE_CLASS, "test" );
+ assertEquals( Color.magenta, c.getBackground() );
+ assertEquals( new Color( 0x000025 ), c.getForeground() );
+ }
+
+ @Test
+ void table() {
+ JTable c = new JTable();
+ c.putClientProperty( FlatClientProperties.STYLE_CLASS, "test" );
+ assertEquals( Color.magenta, c.getBackground() );
+ assertEquals( new Color( 0x000026 ), c.getForeground() );
+ }
+
+ @Test
+ void tableHeader() {
+ JTableHeader c = new JTableHeader();
+ c.putClientProperty( FlatClientProperties.STYLE_CLASS, "test" );
+ assertEquals( Color.magenta, c.getBackground() );
+ assertEquals( new Color( 0x000027 ), c.getForeground() );
+ }
+
+ @Test
+ void textArea() {
+ JTextArea c = new JTextArea();
+ c.putClientProperty( FlatClientProperties.STYLE_CLASS, "test" );
+ assertEquals( Color.magenta, c.getBackground() );
+ assertEquals( new Color( 0x000028 ), c.getForeground() );
+ }
+
+ @Test
+ void textField() {
+ JTextField c = new JTextField();
+ c.putClientProperty( FlatClientProperties.STYLE_CLASS, "test" );
+ assertEquals( Color.magenta, c.getBackground() );
+ assertEquals( new Color( 0x000029 ), c.getForeground() );
+ }
+
+ @Test
+ void textPane() {
+ JTextPane c = new JTextPane();
+ c.putClientProperty( FlatClientProperties.STYLE_CLASS, "test" );
+ assertEquals( Color.magenta, c.getBackground() );
+ assertEquals( new Color( 0x000030 ), c.getForeground() );
+ }
+
+ @Test
+ void toggleButton() {
+ JToggleButton c = new JToggleButton();
+ c.putClientProperty( FlatClientProperties.STYLE_CLASS, "test" );
+ assertEquals( Color.magenta, c.getBackground() );
+ assertEquals( new Color( 0x000031 ), c.getForeground() );
+
+ c.putClientProperty( FlatClientProperties.STYLE_CLASS, "test2" );
+ assertEquals( new Color( 0x003100 ), c.getForeground() );
+ }
+
+ @Test
+ void toolBar() {
+ JToolBar c = new JToolBar();
+ c.putClientProperty( FlatClientProperties.STYLE_CLASS, "test" );
+ assertEquals( Color.magenta, c.getBackground() );
+ assertEquals( new Color( 0x000032 ), c.getForeground() );
+ }
+
+ @Test
+ void toolBarSeparator() {
+ JToolBar.Separator c = new JToolBar.Separator();
+ assertEquals( new Dimension( 0, 7 ), c.getPreferredSize() );
+
+ c.putClientProperty( FlatClientProperties.STYLE_CLASS, "toolbar-separator-test" );
+ assertEquals( new Dimension( 0, 21 ), c.getPreferredSize() );
+
+ c.putClientProperty( FlatClientProperties.STYLE_CLASS, "toolbar-separator-test2" );
+ assertEquals( new Dimension( 0, 31 ), c.getPreferredSize() );
+ }
+
+ @Test
+ void tree() {
+ JTree c = new JTree();
+ c.putClientProperty( FlatClientProperties.STYLE_CLASS, "test" );
+ assertEquals( Color.magenta, c.getBackground() );
+ assertEquals( new Color( 0x000033 ), c.getForeground() );
+ }
+}