--- old/src/share/classes/com/sun/java/swing/plaf/windows/AnimationController.java 2014-05-05 17:28:48.822270200 +0400 +++ new/src/share/classes/com/sun/java/swing/plaf/windows/AnimationController.java 2014-05-05 17:28:48.203191600 +0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, Oracle and/or its affiliates. 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 @@ -130,11 +130,14 @@ //one second seems plausible value duration = 1000; } else { - duration = XPStyle.getXP().getThemeTransitionDuration( - c, part, - normalizeState(oldState), - normalizeState(newState), - Prop.TRANSITIONDURATIONS); + XPStyle xp = XPStyle.getXP(); + duration = (xp != null) + ? xp.getThemeTransitionDuration( + c, part, + normalizeState(oldState), + normalizeState(newState), + Prop.TRANSITIONDURATIONS) + : 1000; } controller.startAnimation(c, part, oldState, newState, duration); } --- old/src/share/classes/com/sun/java/swing/plaf/windows/DesktopProperty.java 2014-05-05 17:28:52.861783200 +0400 +++ new/src/share/classes/com/sun/java/swing/plaf/windows/DesktopProperty.java 2014-05-05 17:28:52.227702700 +0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. 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 @@ -100,16 +100,23 @@ * Updates the UIs of all the known Frames. */ private static void updateAllUIs() { + invalidateStyle(); + Frame appFrames[] = Frame.getFrames(); + for (Frame appFrame : appFrames) { + updateWindowUI(appFrame); + } + } + + /** + * Invalidates the current style in WindowsLookAndFeel. + */ + private static void invalidateStyle() { // Check if the current UI is WindowsLookAndfeel and flush the XP style map. // Note: Change the package test if this class is moved to a different package. Class uiClass = UIManager.getLookAndFeel().getClass(); if (uiClass.getPackage().equals(DesktopProperty.class.getPackage())) { XPStyle.invalidateStyle(); } - Frame appFrames[] = Frame.getFrames(); - for (Frame appFrame : appFrames) { - updateWindowUI(appFrame); - } } /** @@ -205,8 +212,14 @@ * many desktop properties will change at once. */ protected void updateUI() { + scheduleUpdateUI(); + } + + static final void scheduleUpdateUI() { if (!isUpdatePending()) { setUpdatePending(true); + // JDK-8039383: invalidate the cached style as soon as possible + invalidateStyle(); Runnable uiUpdater = new Runnable() { public void run() { updateAllUIs(); --- old/src/share/classes/com/sun/java/swing/plaf/windows/WindowsComboBoxUI.java 2014-05-05 17:28:56.785281400 +0400 +++ new/src/share/classes/com/sun/java/swing/plaf/windows/WindowsComboBoxUI.java 2014-05-05 17:28:56.177704300 +0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. 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 @@ -424,10 +424,11 @@ protected State getState() { State rv; rv = super.getState(); + XPStyle xp = XPStyle.getXP(); if (rv != State.DISABLED && comboBox != null && ! comboBox.isEditable() - && XPStyle.getXP().isSkinDefined(comboBox, - Part.CP_DROPDOWNBUTTONRIGHT)) { + && xp != null && xp.isSkinDefined(comboBox, + Part.CP_DROPDOWNBUTTONRIGHT)) { /* * for non editable ComboBoxes Vista seems to have the * same glyph for all non DISABLED states --- old/src/share/classes/com/sun/java/swing/plaf/windows/WindowsIconFactory.java 2014-05-05 17:29:00.646771800 +0400 +++ new/src/share/classes/com/sun/java/swing/plaf/windows/WindowsIconFactory.java 2014-05-05 17:29:00.016191700 +0400 @@ -692,7 +692,8 @@ } static int getIconWidth() { - return XPStyle.getXP().getSkin(null, Part.MP_POPUPCHECK).getWidth() + XPStyle xp = XPStyle.getXP(); + return ((xp != null) ? xp.getSkin(null, Part.MP_POPUPCHECK).getWidth() : 16) + 2 * OFFSET; } @@ -758,9 +759,13 @@ if (icon != null) { height = icon.getIconHeight() + 2 * OFFSET; } else { - Skin skin = - XPStyle.getXP().getSkin(null, Part.MP_POPUPCHECK); - height = skin.getHeight() + 2 * OFFSET; + XPStyle xp = XPStyle.getXP(); + if (xp != null) { + Skin skin = xp.getSkin(null, Part.MP_POPUPCHECK); + height = skin.getHeight() + 2 * OFFSET; + } else { + height = 16 + 2 * OFFSET; + } } return height; } --- old/src/share/classes/com/sun/java/swing/plaf/windows/WindowsProgressBarUI.java 2014-05-05 17:29:04.931815900 +0400 +++ new/src/share/classes/com/sun/java/swing/plaf/windows/WindowsProgressBarUI.java 2014-05-05 17:29:04.311237100 +0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. 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 @@ -322,8 +322,9 @@ private Rectangle getFullChunkBounds(Rectangle box) { boolean vertical = (progressBar.getOrientation() == JProgressBar.VERTICAL); XPStyle xp = XPStyle.getXP(); - int gap = xp.getInt(progressBar, Part.PP_PROGRESS, null, - Prop.PROGRESSSPACESIZE, 0); + int gap = (xp != null) ? xp.getInt(progressBar, Part.PP_PROGRESS, + null, Prop.PROGRESSSPACESIZE, 0) + : 0; if (!vertical) { int chunksize = box.width+gap; --- old/src/share/classes/com/sun/java/swing/plaf/windows/WindowsTableHeaderUI.java 2014-05-05 17:29:08.879817200 +0400 +++ new/src/share/classes/com/sun/java/swing/plaf/windows/WindowsTableHeaderUI.java 2014-05-05 17:29:08.269239700 +0400 @@ -91,9 +91,10 @@ this.column = column; this.hasRollover = (column == getRolloverColumn()); if (skin == null) { - skin = XPStyle.getXP().getSkin(header, Part.HP_HEADERITEM); + XPStyle xp = XPStyle.getXP(); + skin = (xp != null) ? xp.getSkin(header, Part.HP_HEADERITEM) : null; } - Insets margins = skin.getContentMargin(); + Insets margins = (skin != null) ? skin.getContentMargin() : null; Border border = null; int contentTop = 0; int contentLeft = 0; --- old/src/share/classes/com/sun/java/swing/plaf/windows/XPStyle.java 2014-05-05 17:29:12.824818200 +0400 +++ new/src/share/classes/com/sun/java/swing/plaf/windows/XPStyle.java 2014-05-05 17:29:12.234243200 +0400 @@ -44,6 +44,7 @@ import java.awt.image.*; import java.security.AccessController; import java.util.*; +import java.util.concurrent.atomic.AtomicBoolean; import javax.swing.*; import javax.swing.border.*; @@ -52,6 +53,7 @@ import sun.awt.image.SunWritableRaster; import sun.awt.windows.ThemeReader; +import sun.awt.windows.WToolkit; import sun.security.action.GetPropertyAction; import sun.swing.CachedPainter; @@ -72,6 +74,8 @@ private static Boolean themeActive = null; + private static final AtomicBoolean xpstyleEnabled = WToolkit.getWToolkit().getXPStyleEnabled(); + private HashMap borderMap; private HashMap colorMap; @@ -96,13 +100,12 @@ * are not active or if this is not Windows XP */ static synchronized XPStyle getXP() { + if (themeActive != null && themeActive.booleanValue() != xpstyleEnabled.get()) { + // JDK-8039383: theme changed, schedule updateAllUIs() + DesktopProperty.scheduleUpdateUI(); + } if (themeActive == null) { - Toolkit toolkit = Toolkit.getDefaultToolkit(); - themeActive = - (Boolean)toolkit.getDesktopProperty("win.xpstyle.themeActive"); - if (themeActive == null) { - themeActive = Boolean.FALSE; - } + themeActive = Boolean.valueOf(xpstyleEnabled.get()); if (themeActive.booleanValue()) { GetPropertyAction propertyAction = new GetPropertyAction("swing.noxp"); @@ -180,9 +183,10 @@ * should probably be cached there instead of here. */ Dimension getDimension(Component c, Part part, State state, Prop prop) { - return ThemeReader.getPosition(part.getControlName(c), part.getValue(), - State.getValue(part, state), - prop.getValue()); + Dimension d = ThemeReader.getPosition(part.getControlName(c), part.getValue(), + State.getValue(part, state), + prop.getValue()); + return (d != null) ? d : new Dimension(); } /** Get a named Point (e.g. a location or an offset) value @@ -199,11 +203,7 @@ Dimension d = ThemeReader.getPosition(part.getControlName(c), part.getValue(), State.getValue(part, state), prop.getValue()); - if (d != null) { - return new Point(d.width, d.height); - } else { - return null; - } + return (d != null) ? new Point(d.width, d.height) : new Point(); } /** Get a named Insets value from the current style @@ -217,9 +217,10 @@ * The return value is already cached in those places. */ Insets getMargin(Component c, Part part, State state, Prop prop) { - return ThemeReader.getThemeMargins(part.getControlName(c), part.getValue(), - State.getValue(part, state), - prop.getValue()); + Insets insets = ThemeReader.getThemeMargins(part.getControlName(c), part.getValue(), + State.getValue(part, state), + prop.getValue()); + return (insets != null) ? insets : new Insets(0, 0, 0, 0); } @@ -509,16 +510,17 @@ int boundingWidth = 100; int boundingHeight = 100; - return ThemeReader.getThemeBackgroundContentMargins( + Insets insets = ThemeReader.getThemeBackgroundContentMargins( part.getControlName(null), part.getValue(), 0, boundingWidth, boundingHeight); + return (insets != null) ? insets : new Insets(0, 0, 0, 0); } private int getWidth(State state) { if (size == null) { size = getPartSize(part, state); } - return size.width; + return (size != null) ? size.width : 0; } int getWidth() { @@ -529,7 +531,7 @@ if (size == null) { size = getPartSize(part, state); } - return size.height; + return (size != null) ? size.height : 0; } int getHeight() { --- old/src/windows/classes/sun/awt/windows/ThemeReader.java 2014-05-05 17:29:16.689809000 +0400 +++ new/src/windows/classes/sun/awt/windows/ThemeReader.java 2014-05-05 17:29:16.094233300 +0400 @@ -31,6 +31,7 @@ import java.awt.Point; import java.util.HashMap; import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; @@ -61,6 +62,8 @@ private static final Lock readLock = readWriteLock.readLock(); private static final Lock writeLock = readWriteLock.writeLock(); + private static final AtomicBoolean themeEnabled = WToolkit.getWToolkit().getXPStyleEnabled(); + static void flush() { writeLock.lock(); try { @@ -119,9 +122,14 @@ public static void paintBackground(int[] buffer, String widget, int part, int state, int x, int y, int w, int h, int stride) { + if (!themeEnabled.get()) { + return; + } readLock.lock(); try { paintBackground(buffer, getTheme(widget), part, state, x, y, w, h, stride); + } catch (InternalError ie) { + // JDK-8039383: It should not happen, yet it's better to suppress this exception anyway } finally { readLock.unlock(); } @@ -142,6 +150,9 @@ private static native boolean isThemePartDefined(long theme, int part, int state); public static boolean isThemePartDefined(String widget, int part, int state) { + if (!themeEnabled.get()) { + return false; + } readLock.lock(); try { return isThemePartDefined(getTheme(widget), part, state); --- old/src/windows/classes/sun/awt/windows/WToolkit.java 2014-05-05 17:29:20.431284100 +0400 +++ new/src/windows/classes/sun/awt/windows/WToolkit.java 2014-05-05 17:29:19.811205300 +0400 @@ -61,6 +61,7 @@ import java.util.Locale; import java.util.Map; import java.util.Properties; +import java.util.concurrent.atomic.AtomicBoolean; import sun.font.FontManager; import sun.font.FontManagerFactory; @@ -72,6 +73,9 @@ private static final PlatformLogger log = PlatformLogger.getLogger("sun.awt.windows.WToolkit"); + // Desktop property which specifies whether XP visual styles are in effect + public static final String XPSTYLE_THEME_ACTIVE = "win.xpstyle.themeActive"; + static GraphicsConfiguration config; // System clipboard. @@ -83,6 +87,9 @@ // Windows properties private WDesktopProperties wprops; + // Visual styles enabled? + private final AtomicBoolean xpstyleEnabled = new AtomicBoolean(false); + // Dynamic Layout Resize client code setting protected boolean dynamicLayoutSetting = false; @@ -929,21 +936,27 @@ * Windows doesn't always send WM_SETTINGCHANGE when it should. */ private void windowsSettingChange() { + // JDK-8039383: Have to update the value of XPSTYLE_THEME_ACTIVE property + // as soon as possible to prevent NPE and other errors because theme data + // has become unavailable. + final Map props = wprops != null ? wprops.getProperties() : null; + updateXPStyleEnabled(props.get(XPSTYLE_THEME_ACTIVE)); + EventQueue.invokeLater(new Runnable() { @Override public void run() { - updateProperties(); + updateProperties(props); } }); } - private synchronized void updateProperties() { - if (null == wprops) { - // wprops has not been initialized, so we have nothing to update + private synchronized void updateProperties(final Map props) { + if (null == props) { return; } - Map props = wprops.getProperties(); + updateXPStyleEnabled(props.get(XPSTYLE_THEME_ACTIVE)); + for (String propName : props.keySet()) { Object val = props.get(propName); if (log.isLoggable(PlatformLogger.Level.FINER)) { @@ -953,6 +966,23 @@ } } + private synchronized void updateProperties() { + if (null == wprops) { + // wprops has not been initialized, so we have nothing to update + return; + } + + updateProperties(wprops.getProperties()); + } + + private void updateXPStyleEnabled(final Object dskProp) { + xpstyleEnabled.set(Boolean.TRUE.equals(dskProp)); + } + + public AtomicBoolean getXPStyleEnabled() { + return xpstyleEnabled; + } + @Override public synchronized void addPropertyChangeListener(String name, PropertyChangeListener pcl) { if (name == null) {