8075255: Metal L&F has dependency on the Windows L&F

Reviewed-by: psadhukhan
This commit is contained in:
Sergey Bylokhov 2017-10-18 22:06:24 -07:00
parent 8f0f21d997
commit 4ccdfd542e
6 changed files with 257 additions and 75 deletions

View File

@ -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);
}
}

View File

@ -114,8 +114,8 @@ public class WindowsLookAndFeel extends BasicLookAndFeel
// 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 @@ public class WindowsLookAndFeel extends BasicLookAndFeel
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 @@ public class WindowsLookAndFeel extends BasicLookAndFeel
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 @@ public class WindowsLookAndFeel extends BasicLookAndFeel
}),
"Caret.width",
new DesktopProperty("win.caret.width", null),
new WindowsDesktopProperty("win.caret.width", null),
"CheckBox.font", ControlFont,
"CheckBox.interiorBackground", WindowBackgroundColor,
@ -699,7 +699,7 @@ public class WindowsLookAndFeel extends BasicLookAndFeel
}),
// DeskTop.
"Desktop.background", new DesktopProperty(
"Desktop.background", new WindowsDesktopProperty(
"win.mdi.backgroundColor",
table.get("desktop")),
"Desktop.ancestorInputMap",
@ -761,7 +761,7 @@ public class WindowsLookAndFeel extends BasicLookAndFeel
"FileChooser.useSystemExtensionHiding", Boolean.TRUE,
"FileChooser.usesSingleFilePane", Boolean.TRUE,
"FileChooser.noPlacesBar", new DesktopProperty("win.comdlg.noPlacesBar",
"FileChooser.noPlacesBar", new WindowsDesktopProperty("win.comdlg.noPlacesBar",
Boolean.FALSE),
"FileChooser.ancestorInputMap",
new UIDefaults.LazyInputMap(new Object[] {
@ -802,28 +802,28 @@ public class WindowsLookAndFeel extends BasicLookAndFeel
"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 @@ public class WindowsLookAndFeel extends BasicLookAndFeel
// *** 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 @@ public class WindowsLookAndFeel extends BasicLookAndFeel
/**
* 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 @@ public class WindowsLookAndFeel extends BasicLookAndFeel
}
KeyboardFocusManager.getCurrentKeyboardFocusManager().
removeKeyEventPostProcessor(WindowsRootPaneUI.altProcessor);
DesktopProperty.flushUnreferencedProperties();
WindowsDesktopProperty.flushUnreferencedProperties();
}
@ -2097,7 +2097,7 @@ public class WindowsLookAndFeel extends BasicLookAndFeel
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 @@ public class WindowsLookAndFeel extends BasicLookAndFeel
}
/**
* 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 @@ public class WindowsLookAndFeel extends BasicLookAndFeel
/**
* 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 @@ public class WindowsLookAndFeel extends BasicLookAndFeel
}
}
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 @@ public class WindowsLookAndFeel extends BasicLookAndFeel
}
}
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);

View File

@ -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.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
* 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
@ -22,13 +22,26 @@
* 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.*;
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;
/**
@ -37,10 +50,7 @@ import sun.awt.AppContext;
* <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");
@ -72,7 +82,7 @@ public class DesktopProperty implements UIDefaults.ActiveValue {
* Cleans up any lingering state held by unrefeernced
* DesktopProperties.
*/
static void flushUnreferencedProperties() {
public static void flushUnreferencedProperties() {
WeakPCL pcl;
while ((pcl = (WeakPCL)queue.poll()) != null) {
@ -100,13 +110,7 @@ public class DesktopProperty implements UIDefaults.ActiveValue {
/**
* 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();
}
protected void updateAllUIs() {
Frame appFrames[] = Frame.getFrames();
for (Frame appFrame : appFrames) {
updateWindowUI(appFrame);
@ -247,8 +251,6 @@ public class DesktopProperty implements UIDefaults.ActiveValue {
return key;
}
/**
* As there is typically only one Toolkit, the PropertyChangeListener
* is handled via a WeakReference so as not to pin down the

View File

@ -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);
}
}

View File

@ -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.*;