From bbe245dca3144a1490eb5571be796613a32fc8d8 Mon Sep 17 00:00:00 2001 From: Alexander Potochkin Date: Fri, 6 Nov 2009 19:48:09 +0300 Subject: [PATCH] 6657138: Mutable statics in Windows PL&F (findbugs) Reviewed-by: peterz, hawtin --- .../java/swing/plaf/motif/MotifButtonUI.java | 15 ++- .../swing/plaf/motif/MotifCheckBoxUI.java | 13 ++- .../java/swing/plaf/motif/MotifLabelUI.java | 13 ++- .../swing/plaf/motif/MotifRadioButtonUI.java | 11 +- .../swing/plaf/motif/MotifToggleButtonUI.java | 11 +- .../swing/plaf/windows/WindowsButtonUI.java | 15 ++- .../swing/plaf/windows/WindowsCheckBoxUI.java | 11 +- .../swing/plaf/windows/WindowsLabelUI.java | 13 ++- .../plaf/windows/WindowsRadioButtonUI.java | 11 +- .../plaf/windows/WindowsToggleButtonUI.java | 19 +++- .../javax/swing/plaf/basic/BasicButtonUI.java | 14 ++- .../swing/plaf/basic/BasicCheckBoxUI.java | 11 +- .../javax/swing/plaf/basic/BasicLabelUI.java | 16 ++- .../swing/plaf/basic/BasicRadioButtonUI.java | 10 +- .../swing/plaf/basic/BasicToggleButtonUI.java | 11 +- .../javax/swing/plaf/metal/MetalButtonUI.java | 14 ++- .../swing/plaf/metal/MetalCheckBoxUI.java | 11 +- .../javax/swing/plaf/metal/MetalLabelUI.java | 16 ++- .../swing/plaf/metal/MetalRadioButtonUI.java | 11 +- .../swing/plaf/metal/MetalToggleButtonUI.java | 11 +- .../swing/Security/6657138/ComponentTest.java | 76 +++++++++++++ .../swing/Security/6657138/bug6657138.java | 103 ++++++++++++++++++ 22 files changed, 394 insertions(+), 42 deletions(-) create mode 100644 jdk/test/javax/swing/Security/6657138/ComponentTest.java create mode 100644 jdk/test/javax/swing/Security/6657138/bug6657138.java diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/MotifButtonUI.java b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/MotifButtonUI.java index 5323b0ac786..bc3a224c091 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/MotifButtonUI.java +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/MotifButtonUI.java @@ -25,6 +25,8 @@ package com.sun.java.swing.plaf.motif; +import sun.awt.AppContext; + import javax.swing.*; import javax.swing.border.*; import javax.swing.plaf.basic.*; @@ -46,16 +48,23 @@ import javax.swing.plaf.*; */ public class MotifButtonUI extends BasicButtonUI { - private final static MotifButtonUI motifButtonUI = new MotifButtonUI(); - protected Color selectColor; private boolean defaults_initialized = false; + private static final Object MOTIF_BUTTON_UI_KEY = new Object(); + // ******************************** // Create PLAF // ******************************** - public static ComponentUI createUI(JComponent c){ + public static ComponentUI createUI(JComponent c) { + AppContext appContext = AppContext.getAppContext(); + MotifButtonUI motifButtonUI = + (MotifButtonUI) appContext.get(MOTIF_BUTTON_UI_KEY); + if (motifButtonUI == null) { + motifButtonUI = new MotifButtonUI(); + appContext.put(MOTIF_BUTTON_UI_KEY, motifButtonUI); + } return motifButtonUI; } diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/MotifCheckBoxUI.java b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/MotifCheckBoxUI.java index a356b57caaf..a4354d26981 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/MotifCheckBoxUI.java +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/MotifCheckBoxUI.java @@ -25,6 +25,8 @@ package com.sun.java.swing.plaf.motif; +import sun.awt.AppContext; + import javax.swing.*; import javax.swing.plaf.*; @@ -45,7 +47,7 @@ import java.awt.*; */ public class MotifCheckBoxUI extends MotifRadioButtonUI { - private static final MotifCheckBoxUI motifCheckBoxUI = new MotifCheckBoxUI(); + private static final Object MOTIF_CHECK_BOX_UI_KEY = new Object(); private final static String propertyPrefix = "CheckBox" + "."; @@ -55,7 +57,14 @@ public class MotifCheckBoxUI extends MotifRadioButtonUI { // ******************************** // Create PLAF // ******************************** - public static ComponentUI createUI(JComponent c){ + public static ComponentUI createUI(JComponent c) { + AppContext appContext = AppContext.getAppContext(); + MotifCheckBoxUI motifCheckBoxUI = + (MotifCheckBoxUI) appContext.get(MOTIF_CHECK_BOX_UI_KEY); + if (motifCheckBoxUI == null) { + motifCheckBoxUI = new MotifCheckBoxUI(); + appContext.put(MOTIF_CHECK_BOX_UI_KEY, motifCheckBoxUI); + } return motifCheckBoxUI; } diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/MotifLabelUI.java b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/MotifLabelUI.java index 7b040ea1c7f..bfa958857c8 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/MotifLabelUI.java +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/MotifLabelUI.java @@ -25,6 +25,8 @@ package com.sun.java.swing.plaf.motif; +import sun.awt.AppContext; + import javax.swing.*; import javax.swing.plaf.basic.BasicLabelUI; import javax.swing.plaf.ComponentUI; @@ -44,9 +46,16 @@ import javax.swing.plaf.ComponentUI; */ public class MotifLabelUI extends BasicLabelUI { - static MotifLabelUI sharedInstance = new MotifLabelUI(); + private static final Object MOTIF_LABEL_UI_KEY = new Object(); public static ComponentUI createUI(JComponent c) { - return sharedInstance; + AppContext appContext = AppContext.getAppContext(); + MotifLabelUI motifLabelUI = + (MotifLabelUI) appContext.get(MOTIF_LABEL_UI_KEY); + if (motifLabelUI == null) { + motifLabelUI = new MotifLabelUI(); + appContext.put(MOTIF_LABEL_UI_KEY, motifLabelUI); + } + return motifLabelUI; } } diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/MotifRadioButtonUI.java b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/MotifRadioButtonUI.java index ea3769c2bc6..5029779bc9d 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/MotifRadioButtonUI.java +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/MotifRadioButtonUI.java @@ -25,6 +25,8 @@ package com.sun.java.swing.plaf.motif; +import sun.awt.AppContext; + import javax.swing.*; import javax.swing.border.*; import javax.swing.plaf.basic.BasicRadioButtonUI; @@ -47,7 +49,7 @@ import java.awt.*; */ public class MotifRadioButtonUI extends BasicRadioButtonUI { - private static final MotifRadioButtonUI motifRadioButtonUI = new MotifRadioButtonUI(); + private static final Object MOTIF_RADIO_BUTTON_UI_KEY = new Object(); protected Color focusColor; @@ -57,6 +59,13 @@ public class MotifRadioButtonUI extends BasicRadioButtonUI { // Create PLAF // ******************************** public static ComponentUI createUI(JComponent c) { + AppContext appContext = AppContext.getAppContext(); + MotifRadioButtonUI motifRadioButtonUI = + (MotifRadioButtonUI) appContext.get(MOTIF_RADIO_BUTTON_UI_KEY); + if (motifRadioButtonUI == null) { + motifRadioButtonUI = new MotifRadioButtonUI(); + appContext.put(MOTIF_RADIO_BUTTON_UI_KEY, motifRadioButtonUI); + } return motifRadioButtonUI; } diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/MotifToggleButtonUI.java b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/MotifToggleButtonUI.java index 43af4139dcc..984667e547e 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/MotifToggleButtonUI.java +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/MotifToggleButtonUI.java @@ -25,6 +25,8 @@ package com.sun.java.swing.plaf.motif; +import sun.awt.AppContext; + import java.awt.*; import java.awt.event.*; @@ -48,7 +50,7 @@ import javax.swing.plaf.basic.*; */ public class MotifToggleButtonUI extends BasicToggleButtonUI { - private final static MotifToggleButtonUI motifToggleButtonUI = new MotifToggleButtonUI(); + private static final Object MOTIF_TOGGLE_BUTTON_UI_KEY = new Object(); protected Color selectColor; @@ -58,6 +60,13 @@ public class MotifToggleButtonUI extends BasicToggleButtonUI // Create PLAF // ******************************** public static ComponentUI createUI(JComponent b) { + AppContext appContext = AppContext.getAppContext(); + MotifToggleButtonUI motifToggleButtonUI = + (MotifToggleButtonUI) appContext.get(MOTIF_TOGGLE_BUTTON_UI_KEY); + if (motifToggleButtonUI == null) { + motifToggleButtonUI = new MotifToggleButtonUI(); + appContext.put(MOTIF_TOGGLE_BUTTON_UI_KEY, motifToggleButtonUI); + } return motifToggleButtonUI; } diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsButtonUI.java b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsButtonUI.java index 4ebc563e0cd..2de1f4ec351 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsButtonUI.java +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsButtonUI.java @@ -35,6 +35,7 @@ import java.awt.*; import static com.sun.java.swing.plaf.windows.TMSchema.*; import static com.sun.java.swing.plaf.windows.TMSchema.Part.*; import static com.sun.java.swing.plaf.windows.XPStyle.Skin; +import sun.awt.AppContext; /** @@ -52,8 +53,6 @@ import static com.sun.java.swing.plaf.windows.XPStyle.Skin; */ public class WindowsButtonUI extends BasicButtonUI { - private final static WindowsButtonUI windowsButtonUI = new WindowsButtonUI(); - protected int dashedRectGapX; protected int dashedRectGapY; protected int dashedRectGapWidth; @@ -63,11 +62,19 @@ public class WindowsButtonUI extends BasicButtonUI private boolean defaults_initialized = false; + private static final Object WINDOWS_BUTTON_UI_KEY = new Object(); // ******************************** // Create PLAF // ******************************** - public static ComponentUI createUI(JComponent c){ + public static ComponentUI createUI(JComponent c) { + AppContext appContext = AppContext.getAppContext(); + WindowsButtonUI windowsButtonUI = + (WindowsButtonUI) appContext.get(WINDOWS_BUTTON_UI_KEY); + if (windowsButtonUI == null) { + windowsButtonUI = new WindowsButtonUI(); + appContext.put(WINDOWS_BUTTON_UI_KEY, windowsButtonUI); + } return windowsButtonUI; } @@ -151,7 +158,7 @@ public class WindowsButtonUI extends BasicButtonUI * allocating them in each paint call substantially reduced the time * it took paint to run. Obviously, this method can't be re-entered. */ - private static Rectangle viewRect = new Rectangle(); + private Rectangle viewRect = new Rectangle(); public void paint(Graphics g, JComponent c) { if (XPStyle.getXP() != null) { diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsCheckBoxUI.java b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsCheckBoxUI.java index fa388195a4d..29c8221a66b 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsCheckBoxUI.java +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsCheckBoxUI.java @@ -25,6 +25,8 @@ package com.sun.java.swing.plaf.windows; +import sun.awt.AppContext; + import javax.swing.plaf.basic.*; import javax.swing.*; import javax.swing.plaf.*; @@ -49,7 +51,7 @@ public class WindowsCheckBoxUI extends WindowsRadioButtonUI // of BasicCheckBoxUI because we want to pick up all the // painting changes made in MetalRadioButtonUI. - private static final WindowsCheckBoxUI windowsCheckBoxUI = new WindowsCheckBoxUI(); + private static final Object WINDOWS_CHECK_BOX_UI_KEY = new Object(); private final static String propertyPrefix = "CheckBox" + "."; @@ -59,6 +61,13 @@ public class WindowsCheckBoxUI extends WindowsRadioButtonUI // Create PLAF // ******************************** public static ComponentUI createUI(JComponent c) { + AppContext appContext = AppContext.getAppContext(); + WindowsCheckBoxUI windowsCheckBoxUI = + (WindowsCheckBoxUI) appContext.get(WINDOWS_CHECK_BOX_UI_KEY); + if (windowsCheckBoxUI == null) { + windowsCheckBoxUI = new WindowsCheckBoxUI(); + appContext.put(WINDOWS_CHECK_BOX_UI_KEY, windowsCheckBoxUI); + } return windowsCheckBoxUI; } diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsLabelUI.java b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsLabelUI.java index 5abbf512de2..b0c74100999 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsLabelUI.java +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsLabelUI.java @@ -26,6 +26,8 @@ package com.sun.java.swing.plaf.windows; import sun.swing.SwingUtilities2; +import sun.awt.AppContext; + import java.awt.Color; import java.awt.Graphics; @@ -51,12 +53,19 @@ import javax.swing.plaf.basic.BasicLabelUI; */ public class WindowsLabelUI extends BasicLabelUI { - private final static WindowsLabelUI windowsLabelUI = new WindowsLabelUI(); + private static final Object WINDOWS_LABEL_UI_KEY = new Object(); // ******************************** // Create PLAF // ******************************** - public static ComponentUI createUI(JComponent c){ + public static ComponentUI createUI(JComponent c) { + AppContext appContext = AppContext.getAppContext(); + WindowsLabelUI windowsLabelUI = + (WindowsLabelUI) appContext.get(WINDOWS_LABEL_UI_KEY); + if (windowsLabelUI == null) { + windowsLabelUI = new WindowsLabelUI(); + appContext.put(WINDOWS_LABEL_UI_KEY, windowsLabelUI); + } return windowsLabelUI; } diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsRadioButtonUI.java b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsRadioButtonUI.java index 43665829347..9d784278780 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsRadioButtonUI.java +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsRadioButtonUI.java @@ -25,6 +25,8 @@ package com.sun.java.swing.plaf.windows; +import sun.awt.AppContext; + import javax.swing.plaf.basic.*; import javax.swing.*; import javax.swing.plaf.*; @@ -44,7 +46,7 @@ import java.awt.*; */ public class WindowsRadioButtonUI extends BasicRadioButtonUI { - private static final WindowsRadioButtonUI windowsRadioButtonUI = new WindowsRadioButtonUI(); + private static final Object WINDOWS_RADIO_BUTTON_UI_KEY = new Object(); protected int dashedRectGapX; protected int dashedRectGapY; @@ -59,6 +61,13 @@ public class WindowsRadioButtonUI extends BasicRadioButtonUI // Create PLAF // ******************************** public static ComponentUI createUI(JComponent c) { + AppContext appContext = AppContext.getAppContext(); + WindowsRadioButtonUI windowsRadioButtonUI = + (WindowsRadioButtonUI) appContext.get(WINDOWS_RADIO_BUTTON_UI_KEY); + if (windowsRadioButtonUI == null) { + windowsRadioButtonUI = new WindowsRadioButtonUI(); + appContext.put(WINDOWS_RADIO_BUTTON_UI_KEY, windowsRadioButtonUI); + } return windowsRadioButtonUI; } diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsToggleButtonUI.java b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsToggleButtonUI.java index 3b49ad5ee4e..f7a8707aabe 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsToggleButtonUI.java +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsToggleButtonUI.java @@ -25,6 +25,8 @@ package com.sun.java.swing.plaf.windows; +import sun.awt.AppContext; + import javax.swing.plaf.basic.*; import javax.swing.border.*; import javax.swing.plaf.*; @@ -49,18 +51,25 @@ import java.beans.PropertyChangeEvent; */ public class WindowsToggleButtonUI extends BasicToggleButtonUI { - protected static int dashedRectGapX; - protected static int dashedRectGapY; - protected static int dashedRectGapWidth; - protected static int dashedRectGapHeight; + protected int dashedRectGapX; + protected int dashedRectGapY; + protected int dashedRectGapWidth; + protected int dashedRectGapHeight; protected Color focusColor; - private final static WindowsToggleButtonUI windowsToggleButtonUI = new WindowsToggleButtonUI(); + private static final Object WINDOWS_TOGGLE_BUTTON_UI_KEY = new Object(); private boolean defaults_initialized = false; public static ComponentUI createUI(JComponent b) { + AppContext appContext = AppContext.getAppContext(); + WindowsToggleButtonUI windowsToggleButtonUI = + (WindowsToggleButtonUI) appContext.get(WINDOWS_TOGGLE_BUTTON_UI_KEY); + if (windowsToggleButtonUI == null) { + windowsToggleButtonUI = new WindowsToggleButtonUI(); + appContext.put(WINDOWS_TOGGLE_BUTTON_UI_KEY, windowsToggleButtonUI); + } return windowsToggleButtonUI; } diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicButtonUI.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicButtonUI.java index 5dc98f2c17e..7daf35c7071 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicButtonUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicButtonUI.java @@ -26,6 +26,8 @@ package javax.swing.plaf.basic; import sun.swing.SwingUtilities2; +import sun.awt.AppContext; + import java.awt.*; import java.awt.event.*; import java.io.Serializable; @@ -44,9 +46,6 @@ import javax.swing.text.View; * @author Jeff Dinkins */ public class BasicButtonUI extends ButtonUI{ - // Shared UI object - private final static BasicButtonUI buttonUI = new BasicButtonUI(); - // Visual constants // NOTE: This is not used or set any where. Were we allowed to remove // fields, this would be removed. @@ -61,10 +60,19 @@ public class BasicButtonUI extends ButtonUI{ private final static String propertyPrefix = "Button" + "."; + private static final Object BASIC_BUTTON_UI_KEY = new Object(); + // ******************************** // Create PLAF // ******************************** public static ComponentUI createUI(JComponent c) { + AppContext appContext = AppContext.getAppContext(); + BasicButtonUI buttonUI = + (BasicButtonUI) appContext.get(BASIC_BUTTON_UI_KEY); + if (buttonUI == null) { + buttonUI = new BasicButtonUI(); + appContext.put(BASIC_BUTTON_UI_KEY, buttonUI); + } return buttonUI; } diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicCheckBoxUI.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicCheckBoxUI.java index 443d05999ce..3d048d8b588 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicCheckBoxUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicCheckBoxUI.java @@ -25,6 +25,8 @@ package javax.swing.plaf.basic; +import sun.awt.AppContext; + import javax.swing.*; import java.awt.*; @@ -49,7 +51,7 @@ import java.io.Serializable; */ public class BasicCheckBoxUI extends BasicRadioButtonUI { - private final static BasicCheckBoxUI checkboxUI = new BasicCheckBoxUI(); + private static final Object BASIC_CHECK_BOX_UI_KEY = new Object(); private final static String propertyPrefix = "CheckBox" + "."; @@ -57,6 +59,13 @@ public class BasicCheckBoxUI extends BasicRadioButtonUI { // Create PLAF // ******************************** public static ComponentUI createUI(JComponent b) { + AppContext appContext = AppContext.getAppContext(); + BasicCheckBoxUI checkboxUI = + (BasicCheckBoxUI) appContext.get(BASIC_CHECK_BOX_UI_KEY); + if (checkboxUI == null) { + checkboxUI = new BasicCheckBoxUI(); + appContext.put(BASIC_CHECK_BOX_UI_KEY, checkboxUI); + } return checkboxUI; } diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicLabelUI.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicLabelUI.java index 9ca6dcd4e2c..2e663fb8449 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicLabelUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicLabelUI.java @@ -28,6 +28,8 @@ package javax.swing.plaf.basic; import sun.swing.SwingUtilities2; import sun.swing.DefaultLookup; import sun.swing.UIAction; +import sun.awt.AppContext; + import javax.swing.*; import javax.swing.plaf.*; import javax.swing.text.View; @@ -63,7 +65,7 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener * name in defaults table under the key "LabelUI". */ protected static BasicLabelUI labelUI = new BasicLabelUI(); - private final static BasicLabelUI SAFE_BASIC_LABEL_UI = new BasicLabelUI(); + private static final Object BASIC_LABEL_UI_KEY = new Object(); private Rectangle paintIconR = new Rectangle(); private Rectangle paintTextR = new Rectangle(); @@ -394,10 +396,16 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener public static ComponentUI createUI(JComponent c) { if (System.getSecurityManager() != null) { - return SAFE_BASIC_LABEL_UI; - } else { - return labelUI; + AppContext appContext = AppContext.getAppContext(); + BasicLabelUI safeBasicLabelUI = + (BasicLabelUI) appContext.get(BASIC_LABEL_UI_KEY); + if (safeBasicLabelUI == null) { + safeBasicLabelUI = new BasicLabelUI(); + appContext.put(BASIC_LABEL_UI_KEY, safeBasicLabelUI); + } + return safeBasicLabelUI; } + return labelUI; } public void propertyChange(PropertyChangeEvent e) { diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicRadioButtonUI.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicRadioButtonUI.java index be9d13204c7..1dc781645a6 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicRadioButtonUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicRadioButtonUI.java @@ -32,6 +32,7 @@ import javax.swing.border.*; import javax.swing.plaf.*; import javax.swing.text.View; import sun.swing.SwingUtilities2; +import sun.awt.AppContext; /** @@ -41,7 +42,7 @@ import sun.swing.SwingUtilities2; */ public class BasicRadioButtonUI extends BasicToggleButtonUI { - private final static BasicRadioButtonUI radioButtonUI = new BasicRadioButtonUI(); + private static final Object BASIC_RADIO_BUTTON_UI_KEY = new Object(); protected Icon icon; @@ -53,6 +54,13 @@ public class BasicRadioButtonUI extends BasicToggleButtonUI // Create PLAF // ******************************** public static ComponentUI createUI(JComponent b) { + AppContext appContext = AppContext.getAppContext(); + BasicRadioButtonUI radioButtonUI = + (BasicRadioButtonUI) appContext.get(BASIC_RADIO_BUTTON_UI_KEY); + if (radioButtonUI == null) { + radioButtonUI = new BasicRadioButtonUI(); + appContext.put(BASIC_RADIO_BUTTON_UI_KEY, radioButtonUI); + } return radioButtonUI; } diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicToggleButtonUI.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicToggleButtonUI.java index e519d3202d9..07c2e47feec 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicToggleButtonUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicToggleButtonUI.java @@ -25,6 +25,8 @@ package javax.swing.plaf.basic; +import sun.awt.AppContext; + import java.awt.*; import java.awt.event.*; @@ -43,7 +45,7 @@ import javax.swing.text.View; */ public class BasicToggleButtonUI extends BasicButtonUI { - private final static BasicToggleButtonUI toggleButtonUI = new BasicToggleButtonUI(); + private static final Object BASIC_TOGGLE_BUTTON_UI_KEY = new Object(); private final static String propertyPrefix = "ToggleButton" + "."; @@ -51,6 +53,13 @@ public class BasicToggleButtonUI extends BasicButtonUI { // Create PLAF // ******************************** public static ComponentUI createUI(JComponent b) { + AppContext appContext = AppContext.getAppContext(); + BasicToggleButtonUI toggleButtonUI = + (BasicToggleButtonUI) appContext.get(BASIC_TOGGLE_BUTTON_UI_KEY); + if (toggleButtonUI == null) { + toggleButtonUI = new BasicToggleButtonUI(); + appContext.put(BASIC_TOGGLE_BUTTON_UI_KEY, toggleButtonUI); + } return toggleButtonUI; } diff --git a/jdk/src/share/classes/javax/swing/plaf/metal/MetalButtonUI.java b/jdk/src/share/classes/javax/swing/plaf/metal/MetalButtonUI.java index 9917640cace..659315423fe 100644 --- a/jdk/src/share/classes/javax/swing/plaf/metal/MetalButtonUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/metal/MetalButtonUI.java @@ -26,6 +26,8 @@ package javax.swing.plaf.metal; import sun.swing.SwingUtilities2; +import sun.awt.AppContext; + import javax.swing.*; import javax.swing.border.*; import javax.swing.plaf.basic.*; @@ -49,19 +51,25 @@ import javax.swing.plaf.*; * @author Tom Santos */ public class MetalButtonUI extends BasicButtonUI { - - private final static MetalButtonUI metalButtonUI = new MetalButtonUI(); - // NOTE: These are not really needed, but at this point we can't pull // them. Their values are updated purely for historical reasons. protected Color focusColor; protected Color selectColor; protected Color disabledTextColor; + private static final Object METAL_BUTTON_UI_KEY = new Object(); + // ******************************** // Create PLAF // ******************************** public static ComponentUI createUI(JComponent c) { + AppContext appContext = AppContext.getAppContext(); + MetalButtonUI metalButtonUI = + (MetalButtonUI) appContext.get(METAL_BUTTON_UI_KEY); + if (metalButtonUI == null) { + metalButtonUI = new MetalButtonUI(); + appContext.put(METAL_BUTTON_UI_KEY, metalButtonUI); + } return metalButtonUI; } diff --git a/jdk/src/share/classes/javax/swing/plaf/metal/MetalCheckBoxUI.java b/jdk/src/share/classes/javax/swing/plaf/metal/MetalCheckBoxUI.java index a061ac078a6..650eda000e0 100644 --- a/jdk/src/share/classes/javax/swing/plaf/metal/MetalCheckBoxUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/metal/MetalCheckBoxUI.java @@ -25,6 +25,8 @@ package javax.swing.plaf.metal; +import sun.awt.AppContext; + import javax.swing.*; import javax.swing.plaf.basic.BasicCheckBoxUI; @@ -55,7 +57,7 @@ public class MetalCheckBoxUI extends MetalRadioButtonUI { // of BasicCheckBoxUI because we want to pick up all the // painting changes made in MetalRadioButtonUI. - private final static MetalCheckBoxUI checkboxUI = new MetalCheckBoxUI(); + private static final Object METAL_CHECK_BOX_UI_KEY = new Object(); private final static String propertyPrefix = "CheckBox" + "."; @@ -65,6 +67,13 @@ public class MetalCheckBoxUI extends MetalRadioButtonUI { // Create PlAF // ******************************** public static ComponentUI createUI(JComponent b) { + AppContext appContext = AppContext.getAppContext(); + MetalCheckBoxUI checkboxUI = + (MetalCheckBoxUI) appContext.get(METAL_CHECK_BOX_UI_KEY); + if (checkboxUI == null) { + checkboxUI = new MetalCheckBoxUI(); + appContext.put(METAL_CHECK_BOX_UI_KEY, checkboxUI); + } return checkboxUI; } diff --git a/jdk/src/share/classes/javax/swing/plaf/metal/MetalLabelUI.java b/jdk/src/share/classes/javax/swing/plaf/metal/MetalLabelUI.java index f19fc9962ac..d4a341bea5d 100644 --- a/jdk/src/share/classes/javax/swing/plaf/metal/MetalLabelUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/metal/MetalLabelUI.java @@ -26,6 +26,8 @@ package javax.swing.plaf.metal; import sun.swing.SwingUtilities2; +import sun.awt.AppContext; + import javax.swing.*; import javax.swing.plaf.*; import javax.swing.plaf.basic.*; @@ -51,15 +53,21 @@ public class MetalLabelUI extends BasicLabelUI * name in defaults table under the key "LabelUI". */ protected static MetalLabelUI metalLabelUI = new MetalLabelUI(); - private final static MetalLabelUI SAFE_METAL_LABEL_UI = new MetalLabelUI(); + private static final Object METAL_LABEL_UI_KEY = new Object(); public static ComponentUI createUI(JComponent c) { if (System.getSecurityManager() != null) { - return SAFE_METAL_LABEL_UI; - } else { - return metalLabelUI; + AppContext appContext = AppContext.getAppContext(); + MetalLabelUI safeMetalLabelUI = + (MetalLabelUI) appContext.get(METAL_LABEL_UI_KEY); + if (safeMetalLabelUI == null) { + safeMetalLabelUI = new MetalLabelUI(); + appContext.put(METAL_LABEL_UI_KEY, safeMetalLabelUI); + } + return safeMetalLabelUI; } + return metalLabelUI; } /** diff --git a/jdk/src/share/classes/javax/swing/plaf/metal/MetalRadioButtonUI.java b/jdk/src/share/classes/javax/swing/plaf/metal/MetalRadioButtonUI.java index 088daed9dd3..42a3703a670 100644 --- a/jdk/src/share/classes/javax/swing/plaf/metal/MetalRadioButtonUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/metal/MetalRadioButtonUI.java @@ -26,6 +26,8 @@ package javax.swing.plaf.metal; import sun.swing.SwingUtilities2; +import sun.awt.AppContext; + import java.awt.*; import java.awt.event.*; import javax.swing.*; @@ -53,7 +55,7 @@ import javax.swing.text.View; */ public class MetalRadioButtonUI extends BasicRadioButtonUI { - private static final MetalRadioButtonUI metalRadioButtonUI = new MetalRadioButtonUI(); + private static final Object METAL_RADIO_BUTTON_UI_KEY = new Object(); protected Color focusColor; protected Color selectColor; @@ -65,6 +67,13 @@ public class MetalRadioButtonUI extends BasicRadioButtonUI { // Create PlAF // ******************************** public static ComponentUI createUI(JComponent c) { + AppContext appContext = AppContext.getAppContext(); + MetalRadioButtonUI metalRadioButtonUI = + (MetalRadioButtonUI) appContext.get(METAL_RADIO_BUTTON_UI_KEY); + if (metalRadioButtonUI == null) { + metalRadioButtonUI = new MetalRadioButtonUI(); + appContext.put(METAL_RADIO_BUTTON_UI_KEY, metalRadioButtonUI); + } return metalRadioButtonUI; } diff --git a/jdk/src/share/classes/javax/swing/plaf/metal/MetalToggleButtonUI.java b/jdk/src/share/classes/javax/swing/plaf/metal/MetalToggleButtonUI.java index c6a8ce8ffcc..03b2454b819 100644 --- a/jdk/src/share/classes/javax/swing/plaf/metal/MetalToggleButtonUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/metal/MetalToggleButtonUI.java @@ -26,6 +26,8 @@ package javax.swing.plaf.metal; import sun.swing.SwingUtilities2; +import sun.awt.AppContext; + import java.awt.*; import java.awt.event.*; import java.lang.ref.*; @@ -55,7 +57,7 @@ import java.io.Serializable; */ public class MetalToggleButtonUI extends BasicToggleButtonUI { - private static final MetalToggleButtonUI metalToggleButtonUI = new MetalToggleButtonUI(); + private static final Object METAL_TOGGLE_BUTTON_UI_KEY = new Object(); protected Color focusColor; protected Color selectColor; @@ -67,6 +69,13 @@ public class MetalToggleButtonUI extends BasicToggleButtonUI { // Create PLAF // ******************************** public static ComponentUI createUI(JComponent b) { + AppContext appContext = AppContext.getAppContext(); + MetalToggleButtonUI metalToggleButtonUI = + (MetalToggleButtonUI) appContext.get(METAL_TOGGLE_BUTTON_UI_KEY); + if (metalToggleButtonUI == null) { + metalToggleButtonUI = new MetalToggleButtonUI(); + appContext.put(METAL_TOGGLE_BUTTON_UI_KEY, metalToggleButtonUI); + } return metalToggleButtonUI; } diff --git a/jdk/test/javax/swing/Security/6657138/ComponentTest.java b/jdk/test/javax/swing/Security/6657138/ComponentTest.java new file mode 100644 index 00000000000..a1a3a7b3c6f --- /dev/null +++ b/jdk/test/javax/swing/Security/6657138/ComponentTest.java @@ -0,0 +1,76 @@ +/* + * 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 6657138 + * @summary Verifies that buttons and labels work well after the fix for 6657138 + * @author Alexander Potochkin + */ + +import sun.awt.SunToolkit; + +import javax.swing.*; +import java.awt.*; + +public class ComponentTest extends JFrame { + private static JFrame frame; + + public ComponentTest() { + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + setLayout(new FlowLayout()); + add(new JButton("JButton")); + add(new JToggleButton("JToggleButton")); + add(new JCheckBox("JCheckBox")); + add(new JRadioButton("JRadioButton")); + add(new JLabel("JLabel")); + pack(); + setLocationRelativeTo(null); + } + + + public static void main(String[] args) throws Exception { + SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + frame = new ComponentTest(); + frame.setVisible(true); + } + }); + toolkit.realSync(); + UIManager.LookAndFeelInfo[] lafs = UIManager.getInstalledLookAndFeels(); + for (final UIManager.LookAndFeelInfo laf : lafs) { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + try { + UIManager.setLookAndFeel(laf.getClassName()); + } catch (Exception e) { + new RuntimeException(e); + } + SwingUtilities.updateComponentTreeUI(frame); + } + }); + toolkit.realSync(); + } + } +} diff --git a/jdk/test/javax/swing/Security/6657138/bug6657138.java b/jdk/test/javax/swing/Security/6657138/bug6657138.java new file mode 100644 index 00000000000..5a3562d256e --- /dev/null +++ b/jdk/test/javax/swing/Security/6657138/bug6657138.java @@ -0,0 +1,103 @@ +/* + * 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 6657138 + * @summary Verifies that buttons and labels don't share their ui's across appContexts + * @author Alexander Potochkin + */ + +import sun.awt.SunToolkit; + +import javax.swing.*; +import javax.swing.plaf.ButtonUI; +import javax.swing.plaf.ComponentUI; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +public class bug6657138 implements Runnable { + + private static Map> componentMap = + Collections.synchronizedMap( + new HashMap>()); + + public void run() { + SunToolkit.createNewAppContext(); + try { + testUIMap(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private static void testUIMap() throws Exception { + UIManager.LookAndFeelInfo[] lafs = UIManager.getInstalledLookAndFeels(); + Set components = componentMap.keySet(); + for (JComponent c : components) { + Map uiMap = componentMap.get(c); + + for (UIManager.LookAndFeelInfo laf : lafs) { + if ("Nimbus".equals(laf.getName())) { + // for some unclear reasons + // Nimbus ui delegate for a button is null + // when this method is called from the new AppContext + continue; + } + String className = laf.getClassName(); + UIManager.setLookAndFeel(className); + ComponentUI ui = UIManager.getUI(c); + if (ui == null) { + throw new RuntimeException("UI is null for " + c); + } + if (ui == uiMap.get(laf.getName())) { + throw new RuntimeException( + "Two AppContexts share the same UI delegate! \n" + + c + "\n" + ui); + } + uiMap.put(laf.getName(), ui); + } + } + } + + public static void main(String[] args) throws Exception { + componentMap.put(new JButton("JButton"), + new HashMap()); + componentMap.put(new JToggleButton("JToggleButton"), + new HashMap()); + componentMap.put(new JRadioButton("JRadioButton"), + new HashMap()); + componentMap.put(new JCheckBox("JCheckBox"), + new HashMap()); + componentMap.put(new JCheckBox("JLabel"), + new HashMap()); + testUIMap(); + ThreadGroup group = new ThreadGroup("6657138"); + Thread thread = new Thread(group, new bug6657138()); + thread.start(); + thread.join(); + } +} +