6860433: [Nimbus] Code to set a single slider's thumb background doesn't work as specified
Reviewed-by: rupashka
--- a/jdk/src/share/classes/javax/swing/plaf/nimbus/Defaults.template Wed Dec 16 16:25:08 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/plaf/nimbus/Defaults.template Mon Dec 21 19:26:58 2009 +0300
@@ -90,6 +90,10 @@
*/
private Map<String, Region> registeredRegions =
new HashMap<String, Region>();
+
+ private Map<JComponent, Map<Region, SynthStyle>> overridesCache =
+ new WeakHashMap<JComponent, Map<Region, SynthStyle>>();
+
/**
* Our fallback style to avoid NPEs if the proper style cannot be found in
* this class. Not sure if relying on DefaultSynthStyle is the best choice.
@@ -251,7 +255,11 @@
}
//return the style, if found, or the default style if not found
- return foundStyle == null ? defaultStyle : foundStyle.getStyle(comp);
+ return foundStyle == null ? defaultStyle : foundStyle.getStyle(comp, r);
+ }
+
+ public void clearOverridesCache(JComponent c) {
+ overridesCache.remove(c);
}
/*
@@ -457,15 +465,6 @@
* Cached shared style.
*/
private NimbusStyle style;
- /**
- * A weakly referenced hash map such that if the reference JComponent
- * key is garbage collected then the entry is removed from the map.
- * This cache exists so that when a JComponent has nimbus overrides
- * in its client map, a unique style will be created and returned
- * for that JComponent instance, always. In such a situation each
- * JComponent instance must have its own instance of NimbusStyle.
- */
- private WeakHashMap<JComponent, WeakReference<NimbusStyle>> overridesCache;
/**
* Create a new LazyStyle.
@@ -513,17 +512,21 @@
* Gets the style. Creates it if necessary.
* @return the style
*/
- SynthStyle getStyle(JComponent c) {
+ SynthStyle getStyle(JComponent c, Region r) {
// if the component has overrides, it gets its own unique style
// instead of the shared style.
if (c.getClientProperty("Nimbus.Overrides") != null) {
- if (overridesCache == null)
- overridesCache = new WeakHashMap<JComponent, WeakReference<NimbusStyle>>();
- WeakReference<NimbusStyle> ref = overridesCache.get(c);
- NimbusStyle s = ref == null ? null : ref.get();
+ Map<Region, SynthStyle> map = overridesCache.get(c);
+ SynthStyle s = null;
+ if (map == null) {
+ map = new HashMap<Region, SynthStyle>();
+ overridesCache.put(c, map);
+ } else {
+ s = map.get(r);
+ }
if (s == null) {
s = new NimbusStyle(prefix, c);
- overridesCache.put(c, new WeakReference<NimbusStyle>(s));
+ map.put(r, s);
}
return s;
}
--- a/jdk/src/share/classes/javax/swing/plaf/nimbus/NimbusLookAndFeel.java Wed Dec 16 16:25:08 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/plaf/nimbus/NimbusLookAndFeel.java Mon Dec 21 19:26:58 2009 +0300
@@ -280,11 +280,15 @@
protected boolean shouldUpdateStyleOnEvent(PropertyChangeEvent ev) {
String eName = ev.getPropertyName();
- // Always update when overrides or size variant change
- if ("Nimbus.Overrides" == eName ||
+ // These properties affect style cached inside NimbusDefaults (6860433)
+ if ("name" == eName ||
+ "ancestor" == eName ||
+ "Nimbus.Overrides" == eName ||
"Nimbus.Overrides.InheritDefaults" == eName ||
"JComponent.sizeVariant" == eName) {
+ JComponent c = (JComponent) ev.getSource();
+ defaults.clearOverridesCache(c);
return true;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/plaf/nimbus/ColorCustomizationTest.java Mon Dec 21 19:26:58 2009 +0300
@@ -0,0 +1,165 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ @bug 6860433
+ @summary Tests variuos techniques of Nimbus color customization
+ @author Peter Zhelezniakov
+ @run main ColorCustomizationTest
+*/
+
+import javax.swing.JLabel;
+import javax.swing.SwingUtilities;
+import javax.swing.UIDefaults;
+import javax.swing.UIManager;
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.image.BufferedImage;
+import javax.swing.UnsupportedLookAndFeelException;
+import javax.swing.plaf.ColorUIResource;
+import javax.swing.plaf.nimbus.NimbusLookAndFeel;
+import javax.swing.plaf.synth.Region;
+
+public class ColorCustomizationTest
+{
+ final static int WIDTH = 200;
+ final static int HEIGHT = 100;
+
+ static NimbusLookAndFeel nimbus;
+
+ final JLabel label;
+ final Graphics g;
+
+ ColorCustomizationTest() {
+ label = new JLabel();
+ label.setSize(200, 100);
+
+ g = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_ARGB).getGraphics();
+ }
+
+ public static void main(String[] args) throws Exception {
+ nimbus = new NimbusLookAndFeel();
+ try {
+ UIManager.setLookAndFeel(nimbus);
+ } catch (UnsupportedLookAndFeelException e) {
+ throw new Error("Unable to set Nimbus LAF");
+ }
+ SwingUtilities.invokeAndWait(new Runnable() {
+ @Override public void run() {
+ new ColorCustomizationTest().test();
+ }
+ });
+ }
+
+ void check(Color c) {
+ SwingUtilities.updateComponentTreeUI(label);
+ label.paint(g);
+ if (label.getBackground().getRGB() != c.getRGB()) {
+ System.err.println("Color mismatch!");
+ System.err.println(" found: " + label.getBackground());
+ System.err.println(" expected: " + c);
+ throw new RuntimeException("Test failed");
+ }
+ }
+
+ void test() {
+ testOverrides();
+ testInheritance();
+ testNames();
+ testBaseColor();
+ }
+
+ void testOverrides() {
+ Color defaultColor = label.getBackground();
+
+ // override default background
+ UIDefaults defs = new UIDefaults();
+ defs.put("Label.background", new ColorUIResource(Color.RED));
+ label.putClientProperty("Nimbus.Overrides", defs);
+ check(Color.RED);
+
+ // change overriding color
+ defs = new UIDefaults();
+ defs.put("Label.background", new ColorUIResource(Color.GREEN));
+ label.putClientProperty("Nimbus.Overrides", defs);
+ check(Color.GREEN);
+
+ // remove override
+ label.putClientProperty("Nimbus.Overrides", null);
+ check(defaultColor);
+ }
+
+ void testInheritance() {
+ Color defaultColor = label.getBackground();
+
+ // more specific setting is in global defaults
+ UIManager.put("Label[Enabled].background", new ColorUIResource(Color.RED));
+
+ // less specific one is in overrides
+ UIDefaults defs = new UIDefaults();
+ defs.put("Label.background", new ColorUIResource(Color.GREEN));
+
+ // global wins
+ label.putClientProperty("Nimbus.Overrides", defs);
+ check(Color.RED);
+
+ // now override wins
+ label.putClientProperty("Nimbus.Overrides.InheritDefaults", false);
+ check(Color.GREEN);
+
+ // global is back
+ label.putClientProperty("Nimbus.Overrides.InheritDefaults", true);
+ check(Color.RED);
+
+ // back to default color
+ UIManager.put("Label[Enabled].background", null);
+ label.putClientProperty("Nimbus.Overrides.InheritDefaults", false);
+ label.putClientProperty("Nimbus.Overrides", null);
+ check(defaultColor);
+ }
+
+ void testNames() {
+ Color defaultColor = label.getBackground();
+
+ UIManager.put("\"BlueLabel\"[Enabled].background",
+ new ColorUIResource(Color.BLUE));
+ UIManager.put("\"RedLabel\"[Enabled].background",
+ new ColorUIResource(Color.RED));
+ nimbus.register(Region.LABEL, "\"BlueLabel\"");
+ nimbus.register(Region.LABEL, "\"RedLabel\"");
+
+ label.setName("BlueLabel");
+ check(Color.BLUE);
+ label.setName("RedLabel");
+ check(Color.RED);
+
+ // remove name, color goes back to default
+ label.setName(null);
+ check(defaultColor);
+ }
+
+ void testBaseColor() {
+ UIManager.put("control", Color.GREEN);
+ check(Color.GREEN);
+ }
+}