// 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("SeaGlassStyle.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("SeaGlassStyle.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("SeaGlassStyle.defaults.pcl", pcl);
}
// store the defaults for reuse
ctx.put("SeaGlassStyle.defaults", compiledDefaults);
}
TreeMap<String, Object> defaults = compiledDefaults.get(prefix);
if (defaults == null) {
defaults = new TreeMap<String, Object>();