diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java index 82e77001..9ff1ff0a 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java @@ -928,6 +928,11 @@ public abstract class FlatLaf * Registers a UI defaults getter function that is invoked before the standard getter. * This allows using different UI defaults for special purposes * (e.g. using multiple themes at the same time). + *
+ * The key is passed as parameter to the function. + * If the function returns {@code null}, then the next registered function is invoked. + * If all registered functions return {@code null}, then the current look and feel is asked. + * If the function returns {@link #NULL_VALUE}, then the UI value becomes {@code null}. * * @see #unregisterUIDefaultsGetter(Function) * @see #runWithUIDefaultsGetter(Function, Runnable) @@ -969,6 +974,25 @@ public abstract class FlatLaf * (e.g. using multiple themes at the same time). * If the current look and feel is not FlatLaf, then the getter is ignored and * the given runnable invoked. + *
+ * The key is passed as parameter to the function. + * If the function returns {@code null}, then the next registered function is invoked. + * If all registered functions return {@code null}, then the current look and feel is asked. + * If the function returns {@link #NULL_VALUE}, then the UI value becomes {@code null}. + *
+ * Example: + *
{@code
+ * // create secondary theme
+ * UIDefaults darkDefaults = new FlatDarkLaf().getDefaults();
+ *
+ * // create panel using secondary theme
+ * FlatLaf.runWithUIDefaultsGetter( key -> {
+ * Object value = darkDefaults.get( key );
+ * return (value != null) ? value : FlatLaf.NULL_VALUE;
+ * }, () -> {
+ * // TODO create components that should use secondary theme here
+ * } );
+ * }
*
* @see #registerUIDefaultsGetter(Function)
* @see #unregisterUIDefaultsGetter(Function)
@@ -987,6 +1011,17 @@ public abstract class FlatLaf
runnable.run();
}
+ /**
+ * Special value returned by functions used in {@link #runWithUIDefaultsGetter(Function, Runnable)}
+ * or {@link #registerUIDefaultsGetter(Function)} to indicate that the UI value should
+ * become {@code null}.
+ *
+ * @see #runWithUIDefaultsGetter(Function, Runnable)
+ * @see #registerUIDefaultsGetter(Function)
+ * @since 1.6
+ */
+ public static final Object NULL_VALUE = new Object();
+
//---- class FlatUIDefaults -----------------------------------------------
private class FlatUIDefaults
@@ -999,13 +1034,13 @@ public abstract class FlatLaf
@Override
public Object get( Object key ) {
Object value = getValue( key );
- return (value != null) ? value : super.get( key );
+ return (value != null) ? (value != NULL_VALUE ? value : null) : super.get( key );
}
@Override
public Object get( Object key, Locale l ) {
Object value = getValue( key );
- return (value != null) ? value : super.get( key, l );
+ return (value != null) ? (value != NULL_VALUE ? value : null) : super.get( key, l );
}
private Object getValue( Object key ) {
diff --git a/flatlaf-theme-editor/src/main/java/com/formdev/flatlaf/themeeditor/FlatThemePreview.java b/flatlaf-theme-editor/src/main/java/com/formdev/flatlaf/themeeditor/FlatThemePreview.java
index be8a567c..e2625a24 100644
--- a/flatlaf-theme-editor/src/main/java/com/formdev/flatlaf/themeeditor/FlatThemePreview.java
+++ b/flatlaf-theme-editor/src/main/java/com/formdev/flatlaf/themeeditor/FlatThemePreview.java
@@ -161,6 +161,17 @@ class FlatThemePreview
value = ((ActiveValue)value).createValue( null );
// System.out.println( key + " = " + value );
+
+ // If value is null and is a property that is defined in a core theme,
+ // then force the value to null.
+ // This is necessary for cases where the current application Laf defines a property
+ // but the edited theme does not (or has set the value explicitly to null).
+ // E.g. FlatLightLaf defines Button.focusedBackground, but in FlatDarkLaf
+ // it is not defined. Without this code, the preview for FlatDarkLaf would use
+ // Button.focusedBackground from FlatLightLaf if FlatLightLaf is the current application Laf.
+ if( value == null && FlatThemePropertiesBaseManager.getDefindedCoreKeys().contains( key ) )
+ return FlatLaf.NULL_VALUE;
+
return value;
}
diff --git a/flatlaf-theme-editor/src/main/java/com/formdev/flatlaf/themeeditor/FlatThemePropertiesBaseManager.java b/flatlaf-theme-editor/src/main/java/com/formdev/flatlaf/themeeditor/FlatThemePropertiesBaseManager.java
index 4f77a689..72d7a839 100644
--- a/flatlaf-theme-editor/src/main/java/com/formdev/flatlaf/themeeditor/FlatThemePropertiesBaseManager.java
+++ b/flatlaf-theme-editor/src/main/java/com/formdev/flatlaf/themeeditor/FlatThemePropertiesBaseManager.java
@@ -21,6 +21,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -47,7 +48,8 @@ class FlatThemePropertiesBaseManager
};
private final Map