Styling: basic support for "classes" (similar to CSS classes) using client property FlatLaf.styleClass

This commit is contained in:
Karl Tauber
2021-09-25 14:34:21 +02:00
parent cce91ea16d
commit b6be0462a5
39 changed files with 951 additions and 118 deletions

View File

@@ -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>.
* <p>
* The style rules must be defined in UI defaults either as strings (in CSS syntax)
* or as {@link java.util.Map}&lt;String, Object&gt; (with binary values).
* The key must be in syntax: {@code [style]type.styleClass}, where the type is optional.
* E.g. in FlatLaf properties file:
* <pre>{@code
* [style]Button.primary = borderColor: #08f; background: #08f; foreground: #fff
* [style].secondary = borderColor: #0f8; background: #0f8
* }</pre>
* or in Java code:
* <pre>{@code
* UIManager.put( "[style]Button.primary", "borderColor: #08f; background: #08f; foreground: #fff" );
* UIManager.put( "[style].secondary", "borderColor: #0f8; background: #0f8" );
* }</pre>
* The rule "Button.primary" can be applied to buttons only.
* The rule ".secondary" can be applied to any component.
* <p>
* 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".
* <p>
* <strong>Components</strong> {@link javax.swing.JComponent}<br>
* <strong>Value type</strong> {@link java.lang.String}, {@code String[]} or {@link java.util.List}&lt;String&gt;<br>
*
* @since 2
*/
String STYLE_CLASS = "FlatLaf.styleClass";
/**
* Specifies minimum width of a component.
* <p>

View File

@@ -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,

View File

@@ -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 */

View File

@@ -57,4 +57,10 @@ public class FlatCheckBoxUI
public String getPropertyPrefix() {
return "CheckBox.";
}
/** @since 2 */
@Override
String getStyleType() {
return "CheckBox";
}
}

View File

@@ -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;

View File

@@ -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<Object> 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;

View File

@@ -60,4 +60,10 @@ public class FlatFormattedTextFieldUI
protected String getPropertyPrefix() {
return "FormattedTextField";
}
/** @since 2 */
@Override
String getStyleType() {
return "FormattedTextField";
}
}

View File

@@ -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 );

View File

@@ -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,

View File

@@ -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;

View File

@@ -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 );

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -162,6 +162,12 @@ public class FlatPasswordFieldUI
}
}
/** @since 2 */
@Override
String getStyleType() {
return "PasswordField";
}
/** @since 2 */
@Override
protected Object applyStyleProperty( String key, Object value ) {

View File

@@ -53,4 +53,10 @@ public class FlatPopupMenuSeparatorUI
protected String getPropertyPrefix() {
return "PopupMenuSeparator";
}
/** @since 2 */
@Override
String getStyleType() {
return "PopupMenuSeparator";
}
}

View File

@@ -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 );

View File

@@ -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 );

View File

@@ -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 */

View File

@@ -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,

View File

@@ -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 );

View File

@@ -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 );

View File

@@ -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,

View File

@@ -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 );

View File

@@ -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;

View File

@@ -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 );

View File

@@ -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<String, Class<?>> 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.
* <p>
* The style rules must be defined in UI defaults either as strings (in CSS syntax)
* or as {@link java.util.Map}&lt;String, Object&gt; (with binary values).
* The key must be in syntax: {@code [style]type.styleClass}, where the type is optional.
* E.g. in FlatLaf properties file:
* <pre>{@code
* [style]Button.primary = borderColor: #08f; background: #08f; foreground: #fff
* [style].secondary = borderColor: #0f8; background: #0f8
* }</pre>
* or in Java code:
* <pre>{@code
* UIManager.put( "[style]Button.primary", "borderColor: #08f; background: #08f; foreground: #fff" );
* UIManager.put( "[style].secondary", "borderColor: #0f8; background: #0f8" );
* }</pre>
* The rule "Button.primary" can be applied to buttons only.
* The rule ".secondary" can be applied to any component.
* <p>
* 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:
* <pre>{@code
* return joinStyles(
* UIManager.get( "[style].foo" ),
* UIManager.get( "[style]Button.foo" ) );
* }</pre>
*
* @param styleClass the style class(es) either as string (single class)
* or as {@code String[]} or {@link java.util.List}&lt;String&gt; (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}&lt;String, Object&gt; (with binary values).
* <p>
* 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<String, Object> map1 = (style1 instanceof String)
? parse( (String) style1 )
: (Map<String, Object>) style1;
if( map1 == null )
return style2;
// convert second style to map
Map<String, Object> map2 = (style2 instanceof String)
? parse( (String) style2 )
: (Map<String, Object>) style2;
if( map2 == null )
return style1;
// join two maps
Map<String, Object> 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<Object> 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;
}
};
}

View File

@@ -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;

View File

@@ -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 );

View File

@@ -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;

View File

@@ -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 */

View File

@@ -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;

View File

@@ -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 */

View File

@@ -96,6 +96,11 @@ public class FlatToggleButtonUI
super( shared );
}
@Override
String getStyleType() {
return "ToggleButton";
}
@Override
protected String getPropertyPrefix() {
return "ToggleButton.";

View File

@@ -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 );

View File

@@ -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 */

View File

@@ -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 );

View File

@@ -370,14 +370,16 @@ public class FlatUIUtils
* <li>an (optional) component border
* <li>the (optional) component background
* </ul>
* <p>
*
* Each part is painted only if the corresponding part color is not {@code null}.
* The parts are painted in this order:
* <p>
* <ol>
* <li>background
* <li>focus border
* <li>border
* </ol>
* <p>
*
* <strong>Background</strong>:
* 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 -----------------------------------------

View File

@@ -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;
}

View File

@@ -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<Object> 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<Object> 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() );
}
}