From a79fc1704a80e75b7a0e28f8dac84244b9c3c4ae Mon Sep 17 00:00:00 2001 From: peterz Date: Mon, 31 Aug 2009 13:46:24 +0400 Subject: [PATCH] 6802944: Nimbus initialization is too slow Reviewed-by: jasper --- .../generator/DefaultsGenerator.java | 51 ++-- .../javax/swing/plaf/nimbus/Defaults.template | 249 ++++++++---------- .../javax/swing/plaf/nimbus/DerivedColor.java | 43 +-- .../swing/plaf/nimbus/NimbusLookAndFeel.java | 66 ++++- .../javax/swing/plaf/nimbus/NimbusStyle.java | 190 ++----------- 5 files changed, 229 insertions(+), 370 deletions(-) diff --git a/make/tools/swing-nimbus/classes/org/jdesktop/synthdesigner/generator/DefaultsGenerator.java b/make/tools/swing-nimbus/classes/org/jdesktop/synthdesigner/generator/DefaultsGenerator.java index 948686cb0..eaece226d 100644 --- a/make/tools/swing-nimbus/classes/org/jdesktop/synthdesigner/generator/DefaultsGenerator.java +++ b/make/tools/swing-nimbus/classes/org/jdesktop/synthdesigner/generator/DefaultsGenerator.java @@ -24,6 +24,7 @@ */ package org.jdesktop.synthdesigner.generator; +import java.awt.Color; import org.jdesktop.swingx.designer.Canvas; import org.jdesktop.swingx.designer.font.Typeface; import org.jdesktop.swingx.designer.paint.Matte; @@ -133,11 +134,7 @@ public class DefaultsGenerator { private static void writeColorPalette(StringBuilder uiDefaultInit, List colors) { for (UIPaint color : colors) { - uiDefaultInit.append(" d.put(\"") - .append(color.getName()) - .append("\",") - .append(convertPaint(color.getValue())) - .append(");\n"); + writeMatte(color.getName(), (Matte)color.getValue(), uiDefaultInit); } } @@ -255,12 +252,8 @@ public class DefaultsGenerator { .append("));\n"); break; case COLOR: - uiDefaultInit.append(" d.put(\"") - .append(prefix) - .append(property.getName()) - .append("\", ") - .append(convertPaint((Matte)property.getValue())) - .append(");\n"); + writeMatte(prefix + property.getName(), + (Matte) property.getValue(), uiDefaultInit); break; case FONT: writeTypeFace(prefix.replace("\"", "\\\"") + property.getName(), @@ -300,7 +293,7 @@ public class DefaultsGenerator { private static void writeMatte(String propertyName, Matte matte, StringBuilder uiDefaultInit) { if (matte==null) System.err.println("Error matte is NULL for ["+propertyName+"]"); - uiDefaultInit.append(" d.put(\"") + uiDefaultInit.append(" addColor(d, \"") .append(propertyName) .append("\", ") .append(convertPaint(matte)) @@ -605,27 +598,23 @@ public class DefaultsGenerator { return s.replace("\"", "\\\""); } - private static String convertPaint(PaintModel paint){ - if (paint instanceof Matte){ - Matte matte = (Matte)paint; - if (matte.isAbsolute()){ - String colorParams = convert(matte.getColor()); - if (matte.isUiResource()) { - return "new ColorUIResource(" + colorParams + ")"; - } else { - return colorParams; - } + private static String convertPaint(PaintModel paint) { + if (paint instanceof Matte) { + Matte matte = (Matte) paint; + if (matte.isAbsolute()) { + Color c = matte.getColor(); + return c.getRed() + ", " + c.getGreen() + ", " + + c.getBlue() + ", " + c.getAlpha(); } else { - String s = "getDerivedColor(\"" + - matte.getUiDefaultParentName()+"\","+ - matte.getHueOffset()+"f,"+matte.getSaturationOffset()+ - "f,"+matte.getBrightnessOffset()+"f,"+ - matte.getAlphaOffset(); - if (matte.isUiResource()) { - return s + ")"; - } else { - return s + ",false)"; + String s = "\"" + matte.getUiDefaultParentName() + "\", " + + matte.getHueOffset() + "f, " + + matte.getSaturationOffset() + "f, " + + matte.getBrightnessOffset() + "f, " + + matte.getAlphaOffset(); + if (! matte.isUiResource()) { + s += ", false"; } + return s; } } else { //TODO: What about gradients etc here? diff --git a/src/share/classes/javax/swing/plaf/nimbus/Defaults.template b/src/share/classes/javax/swing/plaf/nimbus/Defaults.template index 492b53583..7f4250bc5 100644 --- a/src/share/classes/javax/swing/plaf/nimbus/Defaults.template +++ b/src/share/classes/javax/swing/plaf/nimbus/Defaults.template @@ -101,14 +101,7 @@ final class ${LAF_NAME}Defaults { */ private FontUIResource defaultFont; - /** - * Map of lists of derived colors keyed by the DerivedColorKeys - */ - private Map derivedColorsMap = - new HashMap(); - - /** Tempory key used for fetching from the derivedColorsMap */ - private final DerivedColorKey tmpDCKey = new DerivedColorKey(); + private ColorTree colorTree = new ColorTree(); /** Listener for changes to user defaults table */ private DefaultsListener defaultsListener = new DefaultsListener(); @@ -117,14 +110,14 @@ final class ${LAF_NAME}Defaults { void initialize() { // add listener for derived colors UIManager.addPropertyChangeListener(defaultsListener); - UIManager.getDefaults().addPropertyChangeListener(defaultsListener); + UIManager.getDefaults().addPropertyChangeListener(colorTree); } /** Called by UIManager when this look and feel is uninstalled. */ void uninitialize() { // remove listener for derived colors - UIManager.getDefaults().removePropertyChangeListener(defaultsListener); UIManager.removePropertyChangeListener(defaultsListener); + UIManager.getDefaults().removePropertyChangeListener(colorTree); } /** @@ -663,22 +656,23 @@ ${UI_DEFAULT_INIT} } } - /** - * Get a derived color, derived colors are shared instances and will be - * updated when its parent UIDefault color changes. - * - * @param uiDefaultParentName The parent UIDefault key - * @param hOffset The hue offset - * @param sOffset The saturation offset - * @param bOffset The brightness offset - * @param aOffset The alpha offset - * @return The stored derived color - */ - public DerivedColor getDerivedColor(String uiDefaultParentName, - float hOffset, float sOffset, - float bOffset, int aOffset){ - return getDerivedColor(uiDefaultParentName, hOffset, sOffset, - bOffset, aOffset, true); + private void addColor(UIDefaults d, String uin, int r, int g, int b, int a) { + Color color = new ColorUIResource(new Color(r, g, b, a)); + colorTree.addColor(uin, color); + d.put(uin, color); + } + + private void addColor(UIDefaults d, String uin, String parentUin, + float hOffset, float sOffset, float bOffset, int aOffset) { + addColor(d, uin, parentUin, hOffset, sOffset, bOffset, aOffset, true); + } + + private void addColor(UIDefaults d, String uin, String parentUin, + float hOffset, float sOffset, float bOffset, + int aOffset, boolean uiResource) { + Color color = getDerivedColor(uin, parentUin, + hOffset, sOffset, bOffset, aOffset, uiResource); + d.put(uin, color); } /** @@ -694,89 +688,110 @@ ${UI_DEFAULT_INIT} * false if it should not be a UIResource * @return The stored derived color */ - public DerivedColor getDerivedColor(String uiDefaultParentName, + public DerivedColor getDerivedColor(String parentUin, float hOffset, float sOffset, float bOffset, int aOffset, boolean uiResource){ - tmpDCKey.set(uiDefaultParentName, hOffset, sOffset, bOffset, aOffset, - uiResource); - DerivedColor color = derivedColorsMap.get(tmpDCKey); - if (color == null){ - if (uiResource) { - color = new DerivedColor.UIResource(uiDefaultParentName, - hOffset, sOffset, bOffset, aOffset); - } else { - color = new DerivedColor(uiDefaultParentName, hOffset, sOffset, - bOffset, aOffset); - } - // calculate the initial value - color.rederiveColor(); - // add the listener so that if the color changes we'll propogate it - color.addPropertyChangeListener(defaultsListener); - // add to the derived colors table - derivedColorsMap.put(new DerivedColorKey(uiDefaultParentName, - hOffset, sOffset, bOffset, aOffset, uiResource),color); + return getDerivedColor(null, parentUin, + hOffset, sOffset, bOffset, aOffset, uiResource); + } + + private DerivedColor getDerivedColor(String uin, String parentUin, + float hOffset, float sOffset, + float bOffset, int aOffset, + boolean uiResource) { + DerivedColor color; + if (uiResource) { + color = new DerivedColor.UIResource(parentUin, + hOffset, sOffset, bOffset, aOffset); + } else { + color = new DerivedColor(parentUin, hOffset, sOffset, + bOffset, aOffset); + } + + if (derivedColors.containsKey(color)) { + return derivedColors.get(color); + } else { + derivedColors.put(color, color); + color.rederiveColor(); /// move to ARP.decodeColor() ? + colorTree.addColor(uin, color); + return color; } - return color; } - /** - * Key class for derived colors - */ - private class DerivedColorKey { - private String uiDefaultParentName; - private float hOffset, sOffset, bOffset; - private int aOffset; - private boolean uiResource; - - DerivedColorKey(){} - - DerivedColorKey(String uiDefaultParentName, float hOffset, - float sOffset, float bOffset, int aOffset, - boolean uiResource) { - set(uiDefaultParentName, hOffset, sOffset, bOffset, aOffset, uiResource); + private Map derivedColors = + new HashMap(); + + private class ColorTree implements PropertyChangeListener { + private Node root = new Node(null, null); + private Map nodes = new HashMap(); + + public Color getColor(String uin) { + return nodes.get(uin).color; } - void set (String uiDefaultParentName, float hOffset, - float sOffset, float bOffset, int aOffset, - boolean uiResource) { - this.uiDefaultParentName = uiDefaultParentName; - this.hOffset = hOffset; - this.sOffset = sOffset; - this.bOffset = bOffset; - this.aOffset = aOffset; - this.uiResource = uiResource; + public void addColor(String uin, Color color) { + Node parent = getParentNode(color); + Node node = new Node(color, parent); + parent.children.add(node); + if (uin != null) { + nodes.put(uin, node); + } } - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof DerivedColorKey)) return false; - DerivedColorKey that = (DerivedColorKey) o; - if (aOffset != that.aOffset) return false; - if (Float.compare(that.bOffset, bOffset) != 0) return false; - if (Float.compare(that.hOffset, hOffset) != 0) return false; - if (Float.compare(that.sOffset, sOffset) != 0) return false; - if (uiDefaultParentName != null ? - !uiDefaultParentName.equals(that.uiDefaultParentName) : - that.uiDefaultParentName != null) return false; - if (this.uiResource != that.uiResource) return false; - return true; + private Node getParentNode(Color color) { + Node parent = root; + if (color instanceof DerivedColor) { + String parentUin = ((DerivedColor)color).getUiDefaultParentName(); + Node p = nodes.get(parentUin); + if (p != null) { + parent = p; + } + } + return parent; + } + + public void update() { + root.update(); } @Override - public int hashCode() { - int result = super.hashCode(); - result = 31 * result + uiDefaultParentName.hashCode(); - result = 31 * result + hOffset != +0.0f ? - Float.floatToIntBits(hOffset) : 0; - result = 31 * result + sOffset != +0.0f ? - Float.floatToIntBits(sOffset) : 0; - result = 31 * result + bOffset != +0.0f ? - Float.floatToIntBits(bOffset) : 0; - result = 31 * result + aOffset; - result = 31 * result + (uiResource ? 1 : 0); - return result; + public void propertyChange(PropertyChangeEvent ev) { + String name = ev.getPropertyName(); + Node node = nodes.get(name); + if (node != null) { + // this is a registered color + node.parent.children.remove(node); + Color color = (Color) ev.getNewValue(); + Node parent = getParentNode(color); + node.set(color, parent); + parent.children.add(node); + node.update(); + } + } + + class Node { + Color color; + Node parent; + List children = new LinkedList(); + + Node(Color color, Node parent) { + set(color, parent); + } + + public void set(Color color, Node parent) { + this.color = color; + this.parent = parent; + } + + public void update() { + if (color instanceof DerivedColor) { + ((DerivedColor)color).rederiveColor(); + } + for (Node child: children) { + child.update(); + } + } } } @@ -786,49 +801,12 @@ ${UI_DEFAULT_INIT} private class DefaultsListener implements PropertyChangeListener { @Override public void propertyChange(PropertyChangeEvent evt) { - Object src = evt.getSource(); - String key = evt.getPropertyName(); - if (key.equals("lookAndFeel")){ + if ("lookAndFeel".equals(evt.getPropertyName())) { // LAF has been installed, this is the first point at which we // can access our defaults table via UIManager so before now // all derived colors will be incorrect. // First we need to update - for (DerivedColor color : derivedColorsMap.values()) { - color.rederiveColor(); - } - } else if (src instanceof DerivedColor && key.equals("rgb")) { - // derived color that is in UIManager defaults has changed - // update all its dependent colors. Don't worry about doing - // this recursively since calling rederiveColor will cause - // another PCE to be fired, ending up here and essentially - // recursing - DerivedColor parentColor = (DerivedColor)src; - String parentKey = null; - Set> entries = - UIManager.getDefaults().entrySet(); - - for (Map.Entry entry : entries) { - Object value = entry.getValue(); - if (value == parentColor) { - parentKey = entry.getKey().toString(); - } - } - - if (parentKey == null) { - //couldn't find the DerivedColor in the UIDefaults map, - //so we just bail. - return; - } - - for (Map.Entry entry : entries) { - Object value = entry.getValue(); - if (value instanceof DerivedColor) { - DerivedColor color = (DerivedColor)entry.getValue(); - if (parentKey.equals(color.getUiDefaultParentName())) { - color.rederiveColor(); - } - } - } + colorTree.update(); } } } @@ -875,4 +853,3 @@ ${UI_DEFAULT_INIT} } } } - diff --git a/src/share/classes/javax/swing/plaf/nimbus/DerivedColor.java b/src/share/classes/javax/swing/plaf/nimbus/DerivedColor.java index 20b7b1aac..56bac5f4f 100644 --- a/src/share/classes/javax/swing/plaf/nimbus/DerivedColor.java +++ b/src/share/classes/javax/swing/plaf/nimbus/DerivedColor.java @@ -39,8 +39,6 @@ import java.beans.PropertyChangeListener; * @author Jasper Potts */ class DerivedColor extends Color { - private final PropertyChangeSupport changeSupport = - new PropertyChangeSupport(this); private final String uiDefaultParentName; private final float hOffset, sOffset, bOffset; private final int aOffset; @@ -79,7 +77,6 @@ class DerivedColor extends Color { * Recalculate the derived color from the UIManager parent color and offsets */ public void rederiveColor() { - int old = argbValue; Color src = UIManager.getColor(uiDefaultParentName); if (src != null) { float[] tmp = Color.RGBtoHSB(src.getRed(), src.getGreen(), src.getBlue(), null); @@ -97,7 +94,6 @@ class DerivedColor extends Color { int alpha = clamp(aOffset); argbValue = (Color.HSBtoRGB(tmp[0], tmp[1], tmp[2]) & 0xFFFFFF) | (alpha << 24); } - changeSupport.firePropertyChange("rgb", old, argbValue); } /** @@ -141,35 +137,6 @@ class DerivedColor extends Color { return result; } - /** - * Add a PropertyChangeListener to the listener list. - * The listener is registered for all properties. - * The same listener object may be added more than once, and will be called - * as many times as it is added. - * If listener is null, no exception is thrown and no action - * is taken. - * - * @param listener The PropertyChangeListener to be added - */ - public void addPropertyChangeListener(PropertyChangeListener listener) { - changeSupport.addPropertyChangeListener(listener); - } - - /** - * Remove a PropertyChangeListener from the listener list. - * This removes a PropertyChangeListener that was registered - * for all properties. - * If listener was added more than once to the same event - * source, it will be notified one less time after being removed. - * If listener is null, or was never added, no exception is - * thrown and no action is taken. - * - * @param listener The PropertyChangeListener to be removed - */ - public void removePropertyChangeListener(PropertyChangeListener listener) { - changeSupport.removePropertyChangeListener(listener); - } - private float clamp(float value) { if (value < 0) { value = 0; @@ -211,5 +178,15 @@ class DerivedColor extends Color { float bOffset, int aOffset) { super(uiDefaultParentName, hOffset, sOffset, bOffset, aOffset); } + + @Override + public boolean equals(Object o) { + return (o instanceof UIResource) && super.equals(o); + } + + @Override + public int hashCode() { + return super.hashCode() + 7; + } } } diff --git a/src/share/classes/javax/swing/plaf/nimbus/NimbusLookAndFeel.java b/src/share/classes/javax/swing/plaf/nimbus/NimbusLookAndFeel.java index 8c5d121b7..3f100bc81 100644 --- a/src/share/classes/javax/swing/plaf/nimbus/NimbusLookAndFeel.java +++ b/src/share/classes/javax/swing/plaf/nimbus/NimbusLookAndFeel.java @@ -40,6 +40,9 @@ import java.awt.Container; import java.awt.Graphics2D; import java.awt.LayoutManager; import java.awt.image.BufferedImage; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.*; import javax.swing.GrayFilter; import javax.swing.Icon; import javax.swing.JToolBar; @@ -87,6 +90,8 @@ public class NimbusLookAndFeel extends SynthLookAndFeel { */ private UIDefaults uiDefaults; + private DefaultsListener defaultsListener = new DefaultsListener(); + /** * Create a new NimbusLookAndFeel. */ @@ -115,8 +120,7 @@ public class NimbusLookAndFeel extends SynthLookAndFeel { defaults.uninitialize(); // clear all cached images to free memory ImageCache.getInstance().flush(); - // remove the listeners and things installed by NimbusStyle - NimbusStyle.uninitialize(); + UIManager.getDefaults().removePropertyChangeListener(defaultsListener); } /** @@ -515,4 +519,62 @@ public class NimbusLookAndFeel extends SynthLookAndFeel { return obj; } } + + private Map> compiledDefaults = null; + private boolean defaultListenerAdded = false; + + static String parsePrefix(String key) { + if (key == null) { + return null; + } + boolean inquotes = false; + for (int i = 0; i < key.length(); i++) { + char c = key.charAt(i); + if (c == '"') { + inquotes = !inquotes; + } else if ((c == '[' || c == '.') && !inquotes) { + return key.substring(0, i); + } + } + return null; + } + + Map getDefaultsForPrefix(String prefix) { + if (compiledDefaults == null) { + compiledDefaults = new HashMap>(); + for (Map.Entry entry: UIManager.getDefaults().entrySet()) { + if (entry.getKey() instanceof String) { + addDefault((String) entry.getKey(), entry.getValue()); + } + } + if (! defaultListenerAdded) { + UIManager.getDefaults().addPropertyChangeListener(defaultsListener); + defaultListenerAdded = true; + } + } + return compiledDefaults.get(prefix); + } + + private void addDefault(String key, Object value) { + String prefix = parsePrefix(key); + if (prefix != null) { + Map keys = compiledDefaults.get(prefix); + if (keys == null) { + keys = new HashMap(); + compiledDefaults.put(prefix, keys); + } + keys.put(key, value); + } + } + + private class DefaultsListener implements PropertyChangeListener { + @Override public void propertyChange(PropertyChangeEvent ev) { + String key = ev.getPropertyName(); + if ("UIDefaults".equals(key)) { + compiledDefaults = null; + } else { + addDefault(key, ev.getNewValue()); + } + } + } } diff --git a/src/share/classes/javax/swing/plaf/nimbus/NimbusStyle.java b/src/share/classes/javax/swing/plaf/nimbus/NimbusStyle.java index 04efc91cf..a8f8b3fc5 100644 --- a/src/share/classes/javax/swing/plaf/nimbus/NimbusStyle.java +++ b/src/share/classes/javax/swing/plaf/nimbus/NimbusStyle.java @@ -26,7 +26,6 @@ package javax.swing.plaf.nimbus; import javax.swing.Painter; -import java.beans.PropertyChangeEvent; import javax.swing.JComponent; import javax.swing.UIDefaults; import javax.swing.UIManager; @@ -39,16 +38,13 @@ import javax.swing.plaf.synth.SynthStyle; import java.awt.Color; import java.awt.Font; import java.awt.Insets; -import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.TreeMap; -import sun.awt.AppContext; /** *

A SynthStyle implementation used by Nimbus. Each Region that has been @@ -232,42 +228,6 @@ public final class NimbusStyle extends SynthStyle { super.installDefaults(ctx); } - static String parsePrefix(String key) { - if (key == null) return null; - boolean inquotes = false; - for (int i=0; i> compiledDefaults = - (Map>) - ctx.get("NimbusStyle.defaults"); - - if (compiledDefaults == null) { - // the entire UIDefaults tables are parsed and compiled into - // this map of maps. The key of the compiledDefaults is the - // prefix for each style, while the value is a map of - // keys->values for that prefix. - compiledDefaults = new HashMap>(); - - // get all the defaults from UIManager.getDefaults() and put them - // into the compiledDefaults - compileDefaults(compiledDefaults, UIManager.getDefaults()); - - // This second statement pulls defaults from the laf defaults - UIDefaults lafDefaults = UIManager.getLookAndFeelDefaults(); - compileDefaults(compiledDefaults, lafDefaults); - - // if it has not already been done, add a listener to both - // UIManager.getDefaults() and UIManager.getLookAndFeelDefaults(). - PropertyChangeListener pcl = (PropertyChangeListener) - ctx.get("NimbusStyle.defaults.pcl"); - - // if pcl is null, then it has not yet been registered with - // the UIManager defaults for this app context - if (pcl == null) { - // create a PCL which will simply clear out the compiled - // defaults from the app context, causing it to be recomputed - // on subsequent passes - pcl = new DefaultsListener(); - // add the PCL to both defaults tables that we pay attention - // to, so that if the UIDefaults are updated, then the - // precompiled defaults will be cleared from the app context - // and recomputed on subsequent passes - UIManager.getDefaults().addPropertyChangeListener(pcl); - UIManager.getLookAndFeelDefaults().addPropertyChangeListener(pcl); - // save the PCL to the app context as a marker indicating - // that the PCL has been registered so we don't end up adding - // more than one listener to the UIDefaults tables. - ctx.put("NimbusStyle.defaults.pcl", pcl); - } - - // store the defaults for reuse - ctx.put("NimbusStyle.defaults", compiledDefaults); - } - - TreeMap defaults = compiledDefaults.get(prefix); + Map defaults = + ((NimbusLookAndFeel) UIManager.getLookAndFeel()). + getDefaultsForPrefix(prefix); // inspect the client properties for the key "Nimbus.Overrides". If the // value is an instance of UIDefaults, then these defaults are used @@ -371,52 +274,6 @@ public final class NimbusStyle extends SynthStyle { } } - // Now that I've accumulated all the defaults pertaining to this - // style, call init which will read these defaults and configure - // the default "values". - init(values, defaults); - } - - /** - * Iterates over all the keys in the specified UIDefaults and compiles - * those keys into the comiledDefaults data structure. It relies on - * parsing the "prefix" out of the key. If the key is not a String or is - * null then it is ignored. In all other cases a prefix is parsed out - * (even if that prefix is the empty String or is a "fake" prefix. That - * is, suppose you had a key Foo~~MySpecial.KeyThing~~. In this case this - * is not a Nimbus formatted key, but we don't care, we treat it as if it - * is. This doesn't pose any harm, it will simply never be used). - * - * @param compiledDefaults - * @param d - */ - private void compileDefaults( - Map> compiledDefaults, - UIDefaults d) { - for (Object obj : new HashSet(d.keySet())) { - if (obj instanceof String) { - String key = (String)obj; - String kp = parsePrefix(key); - if (kp == null) continue; - TreeMap map = compiledDefaults.get(kp); - if (map == null) { - map = new TreeMap(); - compiledDefaults.put(kp, map); - } - map.put(key, d.get(key)); - } - } - } - - /** - * Initializes the given Values object with the defaults - * contained in the given TreeMap. - * - * @param v The Values object to be initialized - * @param myDefaults a map of UIDefaults to use in initializing the Values. - * This map must contain only keys associated with this Style. - */ - private void init(Values v, TreeMap myDefaults) { //a list of the different types of states used by this style. This //list may contain only "standard" states (those defined by Synth), //or it may contain custom states, or it may contain only "standard" @@ -433,7 +290,7 @@ public final class NimbusStyle extends SynthStyle { //"values" stateTypes to be a non-null array. //Otherwise, let the "values" stateTypes be null to indicate that //there are no custom states or custom state ordering - String statesString = (String)myDefaults.get(prefix + ".States"); + String statesString = (String)defaults.get(prefix + ".States"); if (statesString != null) { String s[] = statesString.split(","); for (int i=0; i 0) { - v.stateTypes = states.toArray(new State[states.size()]); + values.stateTypes = states.toArray(new State[states.size()]); } //assign codes for each of the state types @@ -490,7 +347,7 @@ public final class NimbusStyle extends SynthStyle { } //Now iterate over all the keys in the defaults table - for (String key : myDefaults.keySet()) { + for (String key : defaults.keySet()) { //The key is something like JButton.Enabled.backgroundPainter, //or JButton.States, or JButton.background. //Remove the "JButton." portion of the key @@ -528,11 +385,11 @@ public final class NimbusStyle extends SynthStyle { //otherwise, assume it is a property and install it on the //values object if ("contentMargins".equals(property)) { - v.contentMargins = (Insets)myDefaults.get(key); + values.contentMargins = (Insets)defaults.get(key); } else if ("States".equals(property)) { //ignore } else { - v.defaults.put(property, myDefaults.get(key)); + values.defaults.put(property, defaults.get(key)); } } else { //it is possible that the developer has a malformed UIDefaults @@ -582,13 +439,13 @@ public final class NimbusStyle extends SynthStyle { //so put it in the UIDefaults associated with that runtime //state if ("backgroundPainter".equals(property)) { - rs.backgroundPainter = (Painter)myDefaults.get(key); + rs.backgroundPainter = getPainter(defaults, key); } else if ("foregroundPainter".equals(property)) { - rs.foregroundPainter = (Painter) myDefaults.get(key); + rs.foregroundPainter = getPainter(defaults, key); } else if ("borderPainter".equals(property)) { - rs.borderPainter = (Painter) myDefaults.get(key); + rs.borderPainter = getPainter(defaults, key); } else { - rs.defaults.put(property, myDefaults.get(key)); + rs.defaults.put(property, defaults.get(key)); } } } @@ -598,7 +455,15 @@ public final class NimbusStyle extends SynthStyle { Collections.sort(runtimeStates, STATE_COMPARATOR); //finally, set the array of runtime states on the values object - v.states = runtimeStates.toArray(new RuntimeState[runtimeStates.size()]); + values.states = runtimeStates.toArray(new RuntimeState[runtimeStates.size()]); + } + + private Painter getPainter(Map defaults, String key) { + Object p = defaults.get(key); + if (p instanceof UIDefaults.LazyValue) { + p = ((UIDefaults.LazyValue)p).createValue(UIManager.getDefaults()); + } + return (p instanceof Painter ? (Painter)p : null); } /** @@ -1245,15 +1110,4 @@ public final class NimbusStyle extends SynthStyle { return hash; } } - - /** - * This listener is used to listen to the UIDefaults tables and clear out - * the cached-precompiled map of defaults in that case. - */ - private static final class DefaultsListener implements PropertyChangeListener { - @Override - public void propertyChange(PropertyChangeEvent evt) { - AppContext.getAppContext().put("NimbusStyle.defaults", null); - } - } } -- GitLab