提交 a79fc170 编写于 作者: P peterz

6802944: Nimbus initialization is too slow

Reviewed-by: jasper
上级 90725504
......@@ -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<UIPaint> 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?
......
......@@ -101,14 +101,7 @@ final class ${LAF_NAME}Defaults {
*/
private FontUIResource defaultFont;
/**
* Map of lists of derived colors keyed by the DerivedColorKeys
*/
private Map<DerivedColorKey, DerivedColor> derivedColorsMap =
new HashMap<DerivedColorKey, DerivedColor>();
/** 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<DerivedColor, DerivedColor> derivedColors =
new HashMap<DerivedColor, DerivedColor>();
private class ColorTree implements PropertyChangeListener {
private Node root = new Node(null, null);
private Map<String, Node> nodes = new HashMap<String, Node>();
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<Node> children = new LinkedList<Node>();
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<Map.Entry<Object,Object>> 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}
}
}
}
......@@ -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 <code>listener</code> 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 <code>listener</code> was added more than once to the same event
* source, it will be notified one less time after being removed.
* If <code>listener</code> 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;
}
}
}
......@@ -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<String, Map<String, Object>> 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<String, Object> getDefaultsForPrefix(String prefix) {
if (compiledDefaults == null) {
compiledDefaults = new HashMap<String, Map<String, Object>>();
for (Map.Entry<Object, Object> 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<String, Object> keys = compiledDefaults.get(prefix);
if (keys == null) {
keys = new HashMap<String, Object>();
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());
}
}
}
}
......@@ -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;
/**
* <p>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<key.length(); i++) {
char c = key.charAt(i);
if (c == '"') {
inquotes = !inquotes;
} else if ((c == '[' || c == '.') && !inquotes) {
return key.substring(0, i);
}
}
return null;
}
/**
* Called by NimbusLookAndFeel when the look and feel is being uninstalled.
* Performs general cleanup of any app-context specific data.
*/
static void uninitialize() {
// get the appcontext that we've stored data in
AppContext ctx = AppContext.getAppContext();
// get the pcl stored in app context
PropertyChangeListener pcl = (PropertyChangeListener)
ctx.get("NimbusStyle.defaults.pcl");
// if the pcl exists, uninstall it from the UIDefaults tables
if (pcl != null) {
UIManager.getDefaults().removePropertyChangeListener(pcl);
UIManager.getLookAndFeelDefaults().removePropertyChangeListener(pcl);
}
// clear out the compiled defaults
ctx.put("NimbusStyle.defaults", null);
}
/**
* Pulls data out of UIDefaults, if it has not done so already, and sets
* up the internal state.
......@@ -283,66 +243,9 @@ public final class NimbusStyle extends SynthStyle {
// any Nimbus.Overrides)
values = new Values();
// the profiler revealed that a great deal of CPU time and useless
// garbage was being produced by this method and the init method. One
// culprit was the creation and reparsing of the entire UIDefaults
// map on each call to this method where "values" was null. It turns
// out this was happening a lot.
// To remove this bottleneck, we store the compiled TreeMaps of defaults
// in the appContext for reuse. It is nulled whenever the UIDefaults
// changes and recomputed when necessary.
final AppContext ctx = AppContext.getAppContext();
// fetch the defaults from the app context. If null, then create and
// store the compiled defaults
Map<String, TreeMap<String, Object>> compiledDefaults =
(Map<String, TreeMap<String, Object>>)
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<String, TreeMap<String, Object>>();
// 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<String, Object> defaults = compiledDefaults.get(prefix);
Map<String, Object> 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<String, TreeMap<String,Object>> 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<String,Object> map = compiledDefaults.get(kp);
if (map == null) {
map = new TreeMap<String,Object>();
compiledDefaults.put(kp, map);
}
map.put(key, d.get(key));
}
}
}
/**
* Initializes the given <code>Values</code> 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<String, Object> 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<s.length; i++) {
......@@ -442,7 +299,7 @@ public final class NimbusStyle extends SynthStyle {
//this is a non-standard state name, so look for the
//custom state associated with it
String stateName = prefix + "." + s[i];
State customState = (State)myDefaults.get(stateName);
State customState = (State)defaults.get(stateName);
if (customState != null) {
states.add(customState);
}
......@@ -455,7 +312,7 @@ public final class NimbusStyle extends SynthStyle {
//to be non-null. Otherwise, leave it null (meaning, use the
//standard synth states).
if (states.size() > 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<String, Object> 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);
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册