--- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/DesktopProperty.java Tue Oct 17 14:33:32 2017 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,286 +0,0 @@
-/*
- * Copyright (c) 2001, 2016, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.sun.java.swing.plaf.windows;
-
-import java.awt.*;
-import java.beans.*;
-import java.lang.ref.*;
-import javax.swing.*;
-import javax.swing.plaf.*;
-import sun.awt.AppContext;
-
-/**
- * Wrapper for a value from the desktop. The value is lazily looked up, and
- * can be accessed using the <code>UIManager.ActiveValue</code> method
- * <code>createValue</code>. If the underlying desktop property changes this
- * will force the UIs to update all known Frames. You can invoke
- * <code>invalidate</code> to force the value to be fetched again.
- *
- */
-// NOTE: Don't rely on this class staying in this location. It is likely
-// to move to a different package in the future.
-public class DesktopProperty implements UIDefaults.ActiveValue {
- private static final StringBuilder DESKTOP_PROPERTY_UPDATE_PENDING_KEY =
- new StringBuilder("DesktopPropertyUpdatePending");
-
- /**
- * ReferenceQueue of unreferenced WeakPCLs.
- */
- private static final ReferenceQueue<DesktopProperty> queue = new ReferenceQueue<DesktopProperty>();
-
- /**
- * PropertyChangeListener attached to the Toolkit.
- */
- private WeakPCL pcl;
- /**
- * Key used to lookup value from desktop.
- */
- private final String key;
- /**
- * Value to return.
- */
- private Object value;
- /**
- * Fallback value in case we get null from desktop.
- */
- private final Object fallback;
-
-
- /**
- * Cleans up any lingering state held by unrefeernced
- * DesktopProperties.
- */
- static void flushUnreferencedProperties() {
- WeakPCL pcl;
-
- while ((pcl = (WeakPCL)queue.poll()) != null) {
- pcl.dispose();
- }
- }
-
-
- /**
- * Sets whether or not an updateUI call is pending.
- */
- private static synchronized void setUpdatePending(boolean update) {
- AppContext.getAppContext()
- .put(DESKTOP_PROPERTY_UPDATE_PENDING_KEY, update);
- }
-
- /**
- * Returns true if a UI update is pending.
- */
- private static synchronized boolean isUpdatePending() {
- return Boolean.TRUE.equals(AppContext.getAppContext()
- .get(DESKTOP_PROPERTY_UPDATE_PENDING_KEY));
- }
-
- /**
- * Updates the UIs of all the known Frames.
- */
- private static void updateAllUIs() {
- // 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);
- }
- }
-
- /**
- * Updates the UI of the passed in window and all its children.
- */
- private static void updateWindowUI(Window window) {
- SwingUtilities.updateComponentTreeUI(window);
- Window ownedWins[] = window.getOwnedWindows();
- for (Window ownedWin : ownedWins) {
- updateWindowUI(ownedWin);
- }
- }
-
-
- /**
- * Creates a DesktopProperty.
- *
- * @param key Key used in looking up desktop value.
- * @param fallback Value used if desktop property is null.
- */
- public DesktopProperty(String key, Object fallback) {
- this.key = key;
- this.fallback = fallback;
- // The only sure fire way to clear our references is to create a
- // Thread and wait for a reference to be added to the queue.
- // Because it is so rare that you will actually change the look
- // and feel, this stepped is forgoed and a middle ground of
- // flushing references from the constructor is instead done.
- // The implication is that once one DesktopProperty is created
- // there will most likely be n (number of DesktopProperties created
- // by the LookAndFeel) WeakPCLs around, but this number will not
- // grow past n.
- flushUnreferencedProperties();
- }
-
- /**
- * UIManager.LazyValue method, returns the value from the desktop
- * or the fallback value if the desktop value is null.
- */
- public Object createValue(UIDefaults table) {
- if (value == null) {
- value = configureValue(getValueFromDesktop());
- if (value == null) {
- value = configureValue(getDefaultValue());
- }
- }
- return value;
- }
-
- /**
- * Returns the value from the desktop.
- */
- protected Object getValueFromDesktop() {
- Toolkit toolkit = Toolkit.getDefaultToolkit();
-
- if (pcl == null) {
- pcl = new WeakPCL(this, getKey(), UIManager.getLookAndFeel());
- toolkit.addPropertyChangeListener(getKey(), pcl);
- }
-
- return toolkit.getDesktopProperty(getKey());
- }
-
- /**
- * Returns the value to use if the desktop property is null.
- */
- protected Object getDefaultValue() {
- return fallback;
- }
-
- /**
- * Invalidates the current value.
- *
- * @param laf the LookAndFeel this DesktopProperty was created with
- */
- public void invalidate(LookAndFeel laf) {
- invalidate();
- }
-
- /**
- * Invalides the current value so that the next invocation of
- * <code>createValue</code> will ask for the property again.
- */
- public void invalidate() {
- value = null;
- }
-
- /**
- * Requests that all components in the GUI hierarchy be updated
- * to reflect dynamic changes in this {@literal look&feel}. This update occurs
- * by uninstalling and re-installing the UI objects. Requests are
- * batched and collapsed into a single update pass because often
- * many desktop properties will change at once.
- */
- protected void updateUI() {
- if (!isUpdatePending()) {
- setUpdatePending(true);
- Runnable uiUpdater = new Runnable() {
- public void run() {
- updateAllUIs();
- setUpdatePending(false);
- }
- };
- SwingUtilities.invokeLater(uiUpdater);
- }
- }
-
- /**
- * Configures the value as appropriate for a defaults property in
- * the UIDefaults table.
- */
- protected Object configureValue(Object value) {
- if (value != null) {
- if (value instanceof Color) {
- return new ColorUIResource((Color)value);
- }
- else if (value instanceof Font) {
- return new FontUIResource((Font)value);
- }
- else if (value instanceof UIDefaults.LazyValue) {
- value = ((UIDefaults.LazyValue)value).createValue(null);
- }
- else if (value instanceof UIDefaults.ActiveValue) {
- value = ((UIDefaults.ActiveValue)value).createValue(null);
- }
- }
- return value;
- }
-
- /**
- * Returns the key used to lookup the desktop properties value.
- */
- protected String getKey() {
- return key;
- }
-
-
-
- /**
- * As there is typically only one Toolkit, the PropertyChangeListener
- * is handled via a WeakReference so as not to pin down the
- * DesktopProperty.
- */
- private static class WeakPCL extends WeakReference<DesktopProperty>
- implements PropertyChangeListener {
- private String key;
- private LookAndFeel laf;
-
- WeakPCL(DesktopProperty target, String key, LookAndFeel laf) {
- super(target, queue);
- this.key = key;
- this.laf = laf;
- }
-
- public void propertyChange(PropertyChangeEvent pce) {
- DesktopProperty property = get();
-
- if (property == null || laf != UIManager.getLookAndFeel()) {
- // The property was GC'ed, we're no longer interested in
- // PropertyChanges, remove the listener.
- dispose();
- }
- else {
- property.invalidate(laf);
- property.updateUI();
- }
- }
-
- void dispose() {
- Toolkit.getDefaultToolkit().removePropertyChangeListener(key, this);
- }
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsDesktopProperty.java Wed Oct 18 22:06:24 2017 -0700
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2001, 2017, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.java.swing.plaf.windows;
+
+import javax.swing.UIManager;
+
+import sun.swing.plaf.DesktopProperty;
+
+/**
+ * Wrapper for a value from the desktop. The value is lazily looked up, and
+ * can be accessed using the <code>UIManager.ActiveValue</code> method
+ * <code>createValue</code>. If the underlying desktop property changes this
+ * will force the UIs to update all known Frames. You can invoke
+ * <code>invalidate</code> to force the value to be fetched again.
+ */
+public class WindowsDesktopProperty extends DesktopProperty {
+
+ /**
+ * Updates the UIs of all the known Frames.
+ */
+ @Override
+ protected final void updateAllUIs() {
+ // 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(WindowsDesktopProperty.class.getPackage())) {
+ XPStyle.invalidateStyle();
+ }
+ super.updateAllUIs();
+ }
+
+ /**
+ * Creates a WindowsDesktopProperty.
+ *
+ * @param key Key used in looking up desktop value.
+ * @param fallback Value used if desktop property is null.
+ */
+ public WindowsDesktopProperty(String key, Object fallback) {
+ super(key,fallback);
+ }
+}
--- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsLookAndFeel.java Tue Oct 17 14:33:32 2017 -0700
+++ b/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsLookAndFeel.java Wed Oct 18 22:06:24 2017 -0700
@@ -114,8 +114,8 @@
// These properties are not used directly, but are kept as
// private members to avoid being GC'd.
- private DesktopProperty themeActive, dllName, colorName, sizeName;
- private DesktopProperty aaSettings;
+ private WindowsDesktopProperty themeActive, dllName, colorName, sizeName;
+ private WindowsDesktopProperty aaSettings;
private transient LayoutStyle style;
@@ -455,61 +455,61 @@
Object menuItemAcceleratorDelimiter = "+";
- Object ControlBackgroundColor = new DesktopProperty(
+ Object ControlBackgroundColor = new WindowsDesktopProperty(
"win.3d.backgroundColor",
table.get("control"));
- Object ControlLightColor = new DesktopProperty(
+ Object ControlLightColor = new WindowsDesktopProperty(
"win.3d.lightColor",
table.get("controlHighlight"));
- Object ControlHighlightColor = new DesktopProperty(
+ Object ControlHighlightColor = new WindowsDesktopProperty(
"win.3d.highlightColor",
table.get("controlLtHighlight"));
- Object ControlShadowColor = new DesktopProperty(
+ Object ControlShadowColor = new WindowsDesktopProperty(
"win.3d.shadowColor",
table.get("controlShadow"));
- Object ControlDarkShadowColor = new DesktopProperty(
+ Object ControlDarkShadowColor = new WindowsDesktopProperty(
"win.3d.darkShadowColor",
table.get("controlDkShadow"));
- Object ControlTextColor = new DesktopProperty(
+ Object ControlTextColor = new WindowsDesktopProperty(
"win.button.textColor",
table.get("controlText"));
- Object MenuBackgroundColor = new DesktopProperty(
+ Object MenuBackgroundColor = new WindowsDesktopProperty(
"win.menu.backgroundColor",
table.get("menu"));
- Object MenuBarBackgroundColor = new DesktopProperty(
+ Object MenuBarBackgroundColor = new WindowsDesktopProperty(
"win.menubar.backgroundColor",
table.get("menu"));
- Object MenuTextColor = new DesktopProperty(
+ Object MenuTextColor = new WindowsDesktopProperty(
"win.menu.textColor",
table.get("menuText"));
- Object SelectionBackgroundColor = new DesktopProperty(
+ Object SelectionBackgroundColor = new WindowsDesktopProperty(
"win.item.highlightColor",
table.get("textHighlight"));
- Object SelectionTextColor = new DesktopProperty(
+ Object SelectionTextColor = new WindowsDesktopProperty(
"win.item.highlightTextColor",
table.get("textHighlightText"));
- Object WindowBackgroundColor = new DesktopProperty(
+ Object WindowBackgroundColor = new WindowsDesktopProperty(
"win.frame.backgroundColor",
table.get("window"));
- Object WindowTextColor = new DesktopProperty(
+ Object WindowTextColor = new WindowsDesktopProperty(
"win.frame.textColor",
table.get("windowText"));
- Object WindowBorderWidth = new DesktopProperty(
+ Object WindowBorderWidth = new WindowsDesktopProperty(
"win.frame.sizingBorderWidth",
Integer.valueOf(1));
- Object TitlePaneHeight = new DesktopProperty(
+ Object TitlePaneHeight = new WindowsDesktopProperty(
"win.frame.captionHeight",
Integer.valueOf(18));
- Object TitleButtonWidth = new DesktopProperty(
+ Object TitleButtonWidth = new WindowsDesktopProperty(
"win.frame.captionButtonWidth",
Integer.valueOf(16));
- Object TitleButtonHeight = new DesktopProperty(
+ Object TitleButtonHeight = new WindowsDesktopProperty(
"win.frame.captionButtonHeight",
Integer.valueOf(16));
- Object InactiveTextColor = new DesktopProperty(
+ Object InactiveTextColor = new WindowsDesktopProperty(
"win.text.grayedTextColor",
table.get("textInactiveText"));
- Object ScrollbarBackgroundColor = new DesktopProperty(
+ Object ScrollbarBackgroundColor = new WindowsDesktopProperty(
"win.scrollbar.backgroundColor",
table.get("scrollbar"));
Object buttonFocusColor = new FocusColorProperty();
@@ -535,13 +535,13 @@
Object ToolTipFont = sansSerifPlain12;
Object IconFont = ControlFont;
- Object scrollBarWidth = new DesktopProperty("win.scrollbar.width", Integer.valueOf(16));
+ Object scrollBarWidth = new WindowsDesktopProperty("win.scrollbar.width", Integer.valueOf(16));
- Object menuBarHeight = new DesktopProperty("win.menu.height", null);
+ Object menuBarHeight = new WindowsDesktopProperty("win.menu.height", null);
- Object hotTrackingOn = new DesktopProperty("win.item.hotTrackingOn", true);
+ Object hotTrackingOn = new WindowsDesktopProperty("win.item.hotTrackingOn", true);
- Object showMnemonics = new DesktopProperty("win.menu.keyboardCuesOn", Boolean.TRUE);
+ Object showMnemonics = new WindowsDesktopProperty("win.menu.keyboardCuesOn", Boolean.TRUE);
if (useSystemFontSettings) {
MenuFont = getDesktopFontValue("win.menu.font", MenuFont);
@@ -634,7 +634,7 @@
}),
"Caret.width",
- new DesktopProperty("win.caret.width", null),
+ new WindowsDesktopProperty("win.caret.width", null),
"CheckBox.font", ControlFont,
"CheckBox.interiorBackground", WindowBackgroundColor,
@@ -699,7 +699,7 @@
}),
// DeskTop.
- "Desktop.background", new DesktopProperty(
+ "Desktop.background", new WindowsDesktopProperty(
"win.mdi.backgroundColor",
table.get("desktop")),
"Desktop.ancestorInputMap",
@@ -761,8 +761,8 @@
"FileChooser.useSystemExtensionHiding", Boolean.TRUE,
"FileChooser.usesSingleFilePane", Boolean.TRUE,
- "FileChooser.noPlacesBar", new DesktopProperty("win.comdlg.noPlacesBar",
- Boolean.FALSE),
+ "FileChooser.noPlacesBar", new WindowsDesktopProperty("win.comdlg.noPlacesBar",
+ Boolean.FALSE),
"FileChooser.ancestorInputMap",
new UIDefaults.LazyInputMap(new Object[] {
"ESCAPE", "cancelSelection",
@@ -802,28 +802,28 @@
"InternalFrame.minimizeIconBackground", ControlBackgroundColor,
"InternalFrame.resizeIconHighlight", ControlLightColor,
"InternalFrame.resizeIconShadow", ControlShadowColor,
- "InternalFrame.activeBorderColor", new DesktopProperty(
+ "InternalFrame.activeBorderColor", new WindowsDesktopProperty(
"win.frame.activeBorderColor",
table.get("windowBorder")),
- "InternalFrame.inactiveBorderColor", new DesktopProperty(
+ "InternalFrame.inactiveBorderColor", new WindowsDesktopProperty(
"win.frame.inactiveBorderColor",
table.get("windowBorder")),
- "InternalFrame.activeTitleBackground", new DesktopProperty(
+ "InternalFrame.activeTitleBackground", new WindowsDesktopProperty(
"win.frame.activeCaptionColor",
table.get("activeCaption")),
- "InternalFrame.activeTitleGradient", new DesktopProperty(
+ "InternalFrame.activeTitleGradient", new WindowsDesktopProperty(
"win.frame.activeCaptionGradientColor",
table.get("activeCaption")),
- "InternalFrame.activeTitleForeground", new DesktopProperty(
+ "InternalFrame.activeTitleForeground", new WindowsDesktopProperty(
"win.frame.captionTextColor",
table.get("activeCaptionText")),
- "InternalFrame.inactiveTitleBackground", new DesktopProperty(
+ "InternalFrame.inactiveTitleBackground", new WindowsDesktopProperty(
"win.frame.inactiveCaptionColor",
table.get("inactiveCaption")),
- "InternalFrame.inactiveTitleGradient", new DesktopProperty(
+ "InternalFrame.inactiveTitleGradient", new WindowsDesktopProperty(
"win.frame.inactiveCaptionGradientColor",
table.get("inactiveCaption")),
- "InternalFrame.inactiveTitleForeground", new DesktopProperty(
+ "InternalFrame.inactiveTitleForeground", new WindowsDesktopProperty(
"win.frame.inactiveCaptionTextColor",
table.get("inactiveCaptionText")),
@@ -1462,8 +1462,8 @@
// *** ToolTip
"ToolTip.font", ToolTipFont,
- "ToolTip.background", new DesktopProperty("win.tooltip.backgroundColor", table.get("info")),
- "ToolTip.foreground", new DesktopProperty("win.tooltip.textColor", table.get("infoText")),
+ "ToolTip.background", new WindowsDesktopProperty("win.tooltip.backgroundColor", table.get("info")),
+ "ToolTip.foreground", new WindowsDesktopProperty("win.tooltip.textColor", table.get("infoText")),
// *** ToolTipManager
"ToolTipManager.enableToolTipMode", "activeApplication",
@@ -1724,7 +1724,7 @@
/**
* If we support loading of fonts from the desktop this will return
- * a DesktopProperty representing the font. If the font can't be
+ * a WindowsDesktopProperty representing the font. If the font can't be
* represented in the current encoding this will return null and
* turn off the use of system fonts.
*/
@@ -1885,7 +1885,7 @@
}
KeyboardFocusManager.getCurrentKeyboardFocusManager().
removeKeyEventPostProcessor(WindowsRootPaneUI.altProcessor);
- DesktopProperty.flushUnreferencedProperties();
+ WindowsDesktopProperty.flushUnreferencedProperties();
}
@@ -2097,7 +2097,7 @@
private Icon icon;
private String nativeImageName;
private String fallbackName;
- private DesktopProperty desktopProperty;
+ private WindowsDesktopProperty desktopProperty;
ActiveWindowsIcon(String desktopPropertyName,
String nativeImageName, String fallbackName) {
@@ -2194,10 +2194,10 @@
}
/**
- * DesktopProperty for fonts. If a font with the name 'MS Sans Serif'
+ * WindowsDesktopProperty for fonts. If a font with the name 'MS Sans Serif'
* is returned, it is mapped to 'Microsoft Sans Serif'.
*/
- private static class WindowsFontProperty extends DesktopProperty {
+ private static class WindowsFontProperty extends WindowsDesktopProperty {
WindowsFontProperty(String key, Object backup) {
super(key, backup);
}
@@ -2254,10 +2254,11 @@
/**
- * DesktopProperty for fonts that only gets sizes from the desktop,
+ * WindowsDesktopProperty for fonts that only gets sizes from the desktop,
* font name and style are passed into the constructor
*/
- private static class WindowsFontSizeProperty extends DesktopProperty {
+ private static class WindowsFontSizeProperty extends
+ WindowsDesktopProperty {
private String fontName;
private int fontSize;
private int fontStyle;
@@ -2398,7 +2399,7 @@
}
}
- private class TriggerDesktopProperty extends DesktopProperty {
+ private class TriggerDesktopProperty extends WindowsDesktopProperty {
TriggerDesktopProperty(String key) {
super(key, null);
// This call adds a property change listener for the property,
@@ -2567,7 +2568,7 @@
}
}
- private static class FocusColorProperty extends DesktopProperty {
+ private static class FocusColorProperty extends WindowsDesktopProperty {
public FocusColorProperty () {
// Fallback value is never used because of the configureValue method doesn't return null
super("win.3d.backgroundColor", Color.BLACK);
--- a/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalFontDesktopProperty.java Tue Oct 17 14:33:32 2017 -0700
+++ b/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalFontDesktopProperty.java Wed Oct 18 22:06:24 2017 -0700
@@ -22,16 +22,18 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
+
package javax.swing.plaf.metal;
-import java.awt.*;
+import java.awt.Font;
+
+import sun.swing.plaf.DesktopProperty;
/**
* DesktopProperty that only uses font height in configuring font. This
* is only used on Windows.
- *
*/
-class MetalFontDesktopProperty extends com.sun.java.swing.plaf.windows.DesktopProperty {
+final class MetalFontDesktopProperty extends DesktopProperty {
/**
* Maps from metal font theme type as defined in MetalTheme
* to the corresponding desktop property name.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/share/classes/sun/swing/plaf/DesktopProperty.java Wed Oct 18 22:06:24 2017 -0700
@@ -0,0 +1,288 @@
+/*
+ * Copyright (c) 2001, 2017, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.swing.plaf;
+
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.Frame;
+import java.awt.Toolkit;
+import java.awt.Window;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
+
+import javax.swing.LookAndFeel;
+import javax.swing.SwingUtilities;
+import javax.swing.UIDefaults;
+import javax.swing.UIManager;
+import javax.swing.plaf.ColorUIResource;
+import javax.swing.plaf.FontUIResource;
+
+import sun.awt.AppContext;
+
+/**
+ * Wrapper for a value from the desktop. The value is lazily looked up, and
+ * can be accessed using the <code>UIManager.ActiveValue</code> method
+ * <code>createValue</code>. If the underlying desktop property changes this
+ * will force the UIs to update all known Frames. You can invoke
+ * <code>invalidate</code> to force the value to be fetched again.
+ */
+public class DesktopProperty implements UIDefaults.ActiveValue {
+ private static final StringBuilder DESKTOP_PROPERTY_UPDATE_PENDING_KEY =
+ new StringBuilder("DesktopPropertyUpdatePending");
+
+ /**
+ * ReferenceQueue of unreferenced WeakPCLs.
+ */
+ private static final ReferenceQueue<DesktopProperty> queue = new ReferenceQueue<DesktopProperty>();
+
+ /**
+ * PropertyChangeListener attached to the Toolkit.
+ */
+ private WeakPCL pcl;
+ /**
+ * Key used to lookup value from desktop.
+ */
+ private final String key;
+ /**
+ * Value to return.
+ */
+ private Object value;
+ /**
+ * Fallback value in case we get null from desktop.
+ */
+ private final Object fallback;
+
+
+ /**
+ * Cleans up any lingering state held by unrefeernced
+ * DesktopProperties.
+ */
+ public static void flushUnreferencedProperties() {
+ WeakPCL pcl;
+
+ while ((pcl = (WeakPCL)queue.poll()) != null) {
+ pcl.dispose();
+ }
+ }
+
+
+ /**
+ * Sets whether or not an updateUI call is pending.
+ */
+ private static synchronized void setUpdatePending(boolean update) {
+ AppContext.getAppContext()
+ .put(DESKTOP_PROPERTY_UPDATE_PENDING_KEY, update);
+ }
+
+ /**
+ * Returns true if a UI update is pending.
+ */
+ private static synchronized boolean isUpdatePending() {
+ return Boolean.TRUE.equals(AppContext.getAppContext()
+ .get(DESKTOP_PROPERTY_UPDATE_PENDING_KEY));
+ }
+
+ /**
+ * Updates the UIs of all the known Frames.
+ */
+ protected void updateAllUIs() {
+ Frame appFrames[] = Frame.getFrames();
+ for (Frame appFrame : appFrames) {
+ updateWindowUI(appFrame);
+ }
+ }
+
+ /**
+ * Updates the UI of the passed in window and all its children.
+ */
+ private static void updateWindowUI(Window window) {
+ SwingUtilities.updateComponentTreeUI(window);
+ Window ownedWins[] = window.getOwnedWindows();
+ for (Window ownedWin : ownedWins) {
+ updateWindowUI(ownedWin);
+ }
+ }
+
+
+ /**
+ * Creates a DesktopProperty.
+ *
+ * @param key Key used in looking up desktop value.
+ * @param fallback Value used if desktop property is null.
+ */
+ public DesktopProperty(String key, Object fallback) {
+ this.key = key;
+ this.fallback = fallback;
+ // The only sure fire way to clear our references is to create a
+ // Thread and wait for a reference to be added to the queue.
+ // Because it is so rare that you will actually change the look
+ // and feel, this stepped is forgoed and a middle ground of
+ // flushing references from the constructor is instead done.
+ // The implication is that once one DesktopProperty is created
+ // there will most likely be n (number of DesktopProperties created
+ // by the LookAndFeel) WeakPCLs around, but this number will not
+ // grow past n.
+ flushUnreferencedProperties();
+ }
+
+ /**
+ * UIManager.LazyValue method, returns the value from the desktop
+ * or the fallback value if the desktop value is null.
+ */
+ public Object createValue(UIDefaults table) {
+ if (value == null) {
+ value = configureValue(getValueFromDesktop());
+ if (value == null) {
+ value = configureValue(getDefaultValue());
+ }
+ }
+ return value;
+ }
+
+ /**
+ * Returns the value from the desktop.
+ */
+ protected Object getValueFromDesktop() {
+ Toolkit toolkit = Toolkit.getDefaultToolkit();
+
+ if (pcl == null) {
+ pcl = new WeakPCL(this, getKey(), UIManager.getLookAndFeel());
+ toolkit.addPropertyChangeListener(getKey(), pcl);
+ }
+
+ return toolkit.getDesktopProperty(getKey());
+ }
+
+ /**
+ * Returns the value to use if the desktop property is null.
+ */
+ protected Object getDefaultValue() {
+ return fallback;
+ }
+
+ /**
+ * Invalidates the current value.
+ *
+ * @param laf the LookAndFeel this DesktopProperty was created with
+ */
+ public void invalidate(LookAndFeel laf) {
+ invalidate();
+ }
+
+ /**
+ * Invalides the current value so that the next invocation of
+ * <code>createValue</code> will ask for the property again.
+ */
+ public void invalidate() {
+ value = null;
+ }
+
+ /**
+ * Requests that all components in the GUI hierarchy be updated
+ * to reflect dynamic changes in this {@literal look&feel}. This update occurs
+ * by uninstalling and re-installing the UI objects. Requests are
+ * batched and collapsed into a single update pass because often
+ * many desktop properties will change at once.
+ */
+ protected void updateUI() {
+ if (!isUpdatePending()) {
+ setUpdatePending(true);
+ Runnable uiUpdater = new Runnable() {
+ public void run() {
+ updateAllUIs();
+ setUpdatePending(false);
+ }
+ };
+ SwingUtilities.invokeLater(uiUpdater);
+ }
+ }
+
+ /**
+ * Configures the value as appropriate for a defaults property in
+ * the UIDefaults table.
+ */
+ protected Object configureValue(Object value) {
+ if (value != null) {
+ if (value instanceof Color) {
+ return new ColorUIResource((Color)value);
+ }
+ else if (value instanceof Font) {
+ return new FontUIResource((Font)value);
+ }
+ else if (value instanceof UIDefaults.LazyValue) {
+ value = ((UIDefaults.LazyValue)value).createValue(null);
+ }
+ else if (value instanceof UIDefaults.ActiveValue) {
+ value = ((UIDefaults.ActiveValue)value).createValue(null);
+ }
+ }
+ return value;
+ }
+
+ /**
+ * Returns the key used to lookup the desktop properties value.
+ */
+ protected String getKey() {
+ return key;
+ }
+
+ /**
+ * As there is typically only one Toolkit, the PropertyChangeListener
+ * is handled via a WeakReference so as not to pin down the
+ * DesktopProperty.
+ */
+ private static class WeakPCL extends WeakReference<DesktopProperty>
+ implements PropertyChangeListener {
+ private String key;
+ private LookAndFeel laf;
+
+ WeakPCL(DesktopProperty target, String key, LookAndFeel laf) {
+ super(target, queue);
+ this.key = key;
+ this.laf = laf;
+ }
+
+ public void propertyChange(PropertyChangeEvent pce) {
+ DesktopProperty property = get();
+
+ if (property == null || laf != UIManager.getLookAndFeel()) {
+ // The property was GC'ed, we're no longer interested in
+ // PropertyChanges, remove the listener.
+ dispose();
+ }
+ else {
+ property.invalidate(laf);
+ property.updateUI();
+ }
+ }
+
+ void dispose() {
+ Toolkit.getDefaultToolkit().removePropertyChangeListener(key, this);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/com/sun/java/swing/plaf/windows/RevalidateOnPropertyChange.java Wed Oct 18 22:06:24 2017 -0700
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2017, 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
+ * 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.Dimension;
+import java.awt.EventQueue;
+import java.awt.FlowLayout;
+import java.awt.Font;
+import java.awt.Robot;
+import java.awt.Toolkit;
+import java.lang.reflect.Method;
+
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.UIManager;
+import javax.swing.plaf.FontUIResource;
+
+/**
+ * @test
+ * @key headful
+ * @bug 8075255
+ * @summary tests if the desktop property changes this will force the UIs to
+ * update all known Frames
+ * @requires (os.family == "windows")
+ * @modules java.desktop/sun.awt
+ */
+public final class RevalidateOnPropertyChange {
+
+ private static JFrame frame;
+ private static JButton button;
+ private static volatile Dimension sizeAfter;
+ private static volatile Dimension sizeBefore;
+ private static volatile boolean flag;
+
+ public static void main(String[] args) throws Exception {
+ System.setProperty("swing.useSystemFontSettings", "true");
+ UIManager.put("Application.useSystemFontSettings", true);
+
+ // this functionality is supported on windows in "Windows and Metal L&F"
+ test("com.sun.java.swing.plaf.windows.WindowsLookAndFeel",
+ "win.defaultGUI.font",
+ new Font(Font.DIALOG, FontUIResource.BOLD, 40));
+ test("javax.swing.plaf.metal.MetalLookAndFeel",
+ "win.ansiVar.font.height", 70);
+ }
+
+ /**
+ * Emulates the property change via reflection.
+ */
+ static void test(String laf, String prop, Object value) throws Exception {
+ Class cls = Toolkit.class;
+ Method setDesktopProperty =
+ cls.getDeclaredMethod("setDesktopProperty", String.class,
+ Object.class);
+ setDesktopProperty.setAccessible(true);
+
+ UIManager.setLookAndFeel(laf);
+ EventQueue.invokeAndWait(RevalidateOnPropertyChange::createGUI);
+
+ Robot r = new Robot();
+ r.waitForIdle();
+
+ EventQueue.invokeAndWait(() -> {
+ sizeBefore = button.getSize();
+ });
+
+ Toolkit toolkit = Toolkit.getDefaultToolkit();
+ toolkit.addPropertyChangeListener(prop, evt -> flag = true);
+ setDesktopProperty.invoke(toolkit, prop, value);
+ r.waitForIdle();
+
+ EventQueue.invokeAndWait(() -> {
+ sizeAfter = button.getSize();
+ frame.dispose();
+ });
+
+ if (!flag) {
+ throw new RuntimeException("The listener was not notified");
+ }
+ if (sizeAfter.equals(sizeBefore)) {
+ throw new RuntimeException("Size was not changed :" + sizeAfter);
+ }
+ }
+
+ private static void createGUI() {
+ frame = new JFrame();
+ button = new JButton(UIManager.getLookAndFeel().getName());
+ frame.setLayout(new FlowLayout());
+ frame.getContentPane().add(button);
+ frame.setSize(400, 400);
+ frame.setLocationRelativeTo(null);
+ frame.setVisible(true);
+ }
+}
--- a/test/jdk/com/sun/java/swing/plaf/windows/Test6824600.java Tue Oct 17 14:33:32 2017 -0700
+++ b/test/jdk/com/sun/java/swing/plaf/windows/Test6824600.java Wed Oct 18 22:06:24 2017 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2017, 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
@@ -22,14 +22,14 @@
*/
/* @test
- @bug 6824600
+ @bug 6824600 8075255
@summary OOM occurs when setLookAndFeel() is executed in Windows L&F(XP style)
@author Pavel Porvatov
- @modules java.desktop/com.sun.java.swing.plaf.windows
+ @modules java.desktop/sun.swing.plaf
@run main Test6824600
*/
-import com.sun.java.swing.plaf.windows.DesktopProperty;
+import sun.swing.plaf.DesktopProperty;
import java.awt.*;