On Sun, 9 Apr 2023 20:23:55 GMT, John Hendrikx <jhendr...@openjdk.org> wrote:
> With the preferences Map, this could work similar perhaps; set a key to > whatever you want with put, and restore it to its original value by setting > it to null. That's how the current API works, with a little bit of added complexity: interface Preferences { ... /** * Overrides the value of the {@link #appearanceProperty() appearance} property. * <p> * Specifying {@code null} clears the override, which restores the value of the * {@code appearance} property to the platform-provided value. * <p> * Calling this method does not update the {@code appearance} property instantaneously; * instead, the property is only updated after calling {@link #commit()}, or after the * occurrence of an operating system event that causes the {@code appearance} property * to be recomputed. * * @param appearance the platform appearance override, or {@code null} to clear the override */ void setAppearance(Appearance appearance); ... /** * Overrides a key-value mapping. * <p> * If a platform-provided mapping for the key already exists, calling this method overrides * the value that is mapped to the key. If a platform-provided mapping for the key doesn't * exist, this method creates a new mapping. * <p> * Specifying a {@code null} value clears the override, which restores the value mapped to * the key to the platform-provided value. If the platform does not provide a mapping for * the specified key, the mapping is effectively removed. * <p> * Calling this method does not update the mapping instantaneously; instead, the mapping * is only updated after calling {@link #commit()}, or after the occurrence of an operating * system event that causes the mapped value to be recomputed. * * @param key the key * @param value the new value, or {@code null} to clear the override * @throws NullPointerException if {@code key} is null * @throws IllegalArgumentException if a platform-provided mapping for the key exists, and * the specified value is an instance of a different class * than the platform-provided value * @return the previous value associated with {@code key} */ <T> T override(String key, T value); /** * Commits outstanding overridden preferences, which also causes the values of derived * properties to be recomputed. */ void commit(); } It is very likely the case that changing preferences can lead to very expensive operations in large real-world applications. For example, style themes or the entire user interface may be recreated, icons/images may be loaded, etc. The `Preferences` implementation accounts for this by firing only a single invalidation notification, even when multiple platform preferences have changed. The documentation of `Preferences` contains guidance for users of this API: * @implNote In many cases, multiple platform preferences can change at the same time. * For example, switching from light to dark mode changes various foreground elements to light * colors, and various background elements to dark colors. * <p> * The {@code Preferences} implementation returned from this method fires a single invalidation * event for such bulk changes. If a listener performs potentially heavy work, such as recreating * and applying CSS themes, it might be beneficial to use {@link javafx.beans.InvalidationListener} * instead of {@link javafx.collections.MapChangeListener} to prevent the listener from firing * multiple times in bulk change scenarios. This works when the changes originate from the OS, but it doesn't work when an application overrides preference mappings manually. `ObservableMap` doesn't support bulk changes, so repeatedly calling `override(...)` would end up firing multiple change notifications, and subscribers would have no way of knowing when the bulk change transaction has ended. That's where the concept of _uncommitted modifications_ comes into play: calling `override(...)` or any of the property setters like `setAppearance(...)` doesn't apply the changes immediately, it delays those changes until `commit()` is called or until an OS event causes the preference to be recomputed. When that happens, a single invalidation notification is fired, the same as it would have if the change originated from the OS. ------------- PR Comment: https://git.openjdk.org/jfx/pull/1014#issuecomment-1502081527