From 63810a5c4292cd5f18ca5eea9600d20becd009f5 Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Thu, 3 Sep 2009 19:42:27 +0400 Subject: [PATCH] 6657026: Numerous static security flaws in Swing (findbugs) Reviewed-by: hawtin, peterz --- .../classes/javax/swing/ToolTipManager.java | 15 +- .../share/classes/javax/swing/UIManager.java | 38 +-- .../swing/plaf/basic/BasicSplitPaneUI.java | 10 +- .../javax/swing/plaf/metal/MetalBumps.java | 62 ++--- .../plaf/metal/MetalInternalFrameUI.java | 10 +- .../javax/swing/plaf/metal/MetalSliderUI.java | 23 +- .../swing/ToolTipManager/Test6657026.java | 74 ++++++ .../javax/swing/UIManager/Test6657026.java | 59 +++++ .../basic/BasicSplitPaneUI/Test6657026.java | 82 ++++++ .../plaf/metal/MetalBorders/Test6657026.java | 91 +++++++ .../plaf/metal/MetalBumps/Test6657026.java | 238 ++++++++++++++++++ .../MetalInternalFrameUI/Test6657026.java | 60 +++++ .../plaf/metal/MetalSliderUI/Test6657026.java | 67 +++++ 13 files changed, 734 insertions(+), 95 deletions(-) create mode 100644 jdk/test/javax/swing/ToolTipManager/Test6657026.java create mode 100644 jdk/test/javax/swing/UIManager/Test6657026.java create mode 100644 jdk/test/javax/swing/plaf/basic/BasicSplitPaneUI/Test6657026.java create mode 100644 jdk/test/javax/swing/plaf/metal/MetalBorders/Test6657026.java create mode 100644 jdk/test/javax/swing/plaf/metal/MetalBumps/Test6657026.java create mode 100644 jdk/test/javax/swing/plaf/metal/MetalInternalFrameUI/Test6657026.java create mode 100644 jdk/test/javax/swing/plaf/metal/MetalSliderUI/Test6657026.java diff --git a/jdk/src/share/classes/javax/swing/ToolTipManager.java b/jdk/src/share/classes/javax/swing/ToolTipManager.java index 6ee279bff36..63258349a47 100644 --- a/jdk/src/share/classes/javax/swing/ToolTipManager.java +++ b/jdk/src/share/classes/javax/swing/ToolTipManager.java @@ -1,5 +1,5 @@ /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-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 @@ -27,10 +27,7 @@ package javax.swing; import java.awt.event.*; -import java.applet.*; import java.awt.*; -import java.io.Serializable; -import sun.swing.UIAction; /** * Manages all the ToolTips in the system. @@ -60,7 +57,7 @@ public class ToolTipManager extends MouseAdapter implements MouseMotionListener JComponent insideComponent; MouseEvent mouseEvent; boolean showImmediately; - final static ToolTipManager sharedInstance = new ToolTipManager(); + private static final Object TOOL_TIP_MANAGER_KEY = new Object(); transient Popup tipWindow; /** The Window tip is being displayed in. This will be non-null if * the Window tip is in differs from that of insideComponent's Window. @@ -345,7 +342,13 @@ public class ToolTipManager extends MouseAdapter implements MouseMotionListener * @return a shared ToolTipManager object */ public static ToolTipManager sharedInstance() { - return sharedInstance; + Object value = SwingUtilities.appContextGet(TOOL_TIP_MANAGER_KEY); + if (value instanceof ToolTipManager) { + return (ToolTipManager) value; + } + ToolTipManager manager = new ToolTipManager(); + SwingUtilities.appContextPut(TOOL_TIP_MANAGER_KEY, manager); + return manager; } // add keylistener here to trigger tip for access diff --git a/jdk/src/share/classes/javax/swing/UIManager.java b/jdk/src/share/classes/javax/swing/UIManager.java index e4c7c7c687d..4dee6f3198a 100644 --- a/jdk/src/share/classes/javax/swing/UIManager.java +++ b/jdk/src/share/classes/javax/swing/UIManager.java @@ -1,5 +1,5 @@ /* - * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-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 @@ -197,6 +197,8 @@ public class UIManager implements Serializable Vector auxLookAndFeels = null; SwingPropertyChangeSupport changeSupport; + LookAndFeelInfo[] installedLAFs; + UIDefaults getLookAndFeelDefaults() { return tables[0]; } void setLookAndFeelDefaults(UIDefaults x) { tables[0] = x; } @@ -227,18 +229,6 @@ public class UIManager implements Serializable */ private static final Object classLock = new Object(); - - /* Cache the last referenced LAFState to improve performance - * when accessing it. The cache is based on last thread rather - * than last AppContext because of the cost of looking up the - * AppContext each time. Since most Swing UI work is on the - * EventDispatchThread, this hits often enough to justify the - * overhead. (4193032) - */ - private static Thread currentLAFStateThread = null; - private static LAFState currentLAFState = null; - - /** * Return the LAFState object, lazily create one if necessary. * All access to the LAFState fields is done via this method, @@ -248,13 +238,6 @@ public class UIManager implements Serializable * */ private static LAFState getLAFState() { - // First check whether we're running on the same thread as - // the last request. - Thread thisThread = Thread.currentThread(); - if (thisThread == currentLAFStateThread) { - return currentLAFState; - } - LAFState rv = (LAFState)SwingUtilities.appContextGet( SwingUtilities2.LAF_STATE_KEY); if (rv == null) { @@ -268,10 +251,6 @@ public class UIManager implements Serializable } } } - - currentLAFStateThread = thisThread; - currentLAFState = rv; - return rv; } @@ -431,7 +410,10 @@ public class UIManager implements Serializable */ public static LookAndFeelInfo[] getInstalledLookAndFeels() { maybeInitialize(); - LookAndFeelInfo[] ilafs = installedLAFs; + LookAndFeelInfo[] ilafs = getLAFState().installedLAFs; + if (ilafs == null) { + ilafs = installedLAFs; + } LookAndFeelInfo[] rv = new LookAndFeelInfo[ilafs.length]; System.arraycopy(ilafs, 0, rv, 0, ilafs.length); return rv; @@ -453,9 +435,10 @@ public class UIManager implements Serializable public static void setInstalledLookAndFeels(LookAndFeelInfo[] infos) throws SecurityException { + maybeInitialize(); LookAndFeelInfo[] newInfos = new LookAndFeelInfo[infos.length]; System.arraycopy(infos, 0, newInfos, 0, infos.length); - installedLAFs = newInfos; + getLAFState().installedLAFs = newInfos; } @@ -1307,10 +1290,11 @@ public class UIManager implements Serializable } } - installedLAFs = new LookAndFeelInfo[ilafs.size()]; + LookAndFeelInfo[] installedLAFs = new LookAndFeelInfo[ilafs.size()]; for(int i = 0; i < ilafs.size(); i++) { installedLAFs[i] = ilafs.elementAt(i); } + getLAFState().installedLAFs = installedLAFs; } diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicSplitPaneUI.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicSplitPaneUI.java index b35a75ed700..0be46948712 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicSplitPaneUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicSplitPaneUI.java @@ -1,5 +1,5 @@ /* - * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-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 @@ -31,14 +31,12 @@ import sun.swing.DefaultLookup; import sun.swing.UIAction; import javax.swing.*; import javax.swing.border.Border; -import javax.swing.event.*; import java.awt.*; import java.awt.event.*; import java.awt.peer.ComponentPeer; import java.awt.peer.LightweightPeer; import java.beans.*; import java.util.*; -import javax.swing.plaf.ActionMapUIResource; import javax.swing.plaf.SplitPaneUI; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.UIResource; @@ -106,13 +104,13 @@ public class BasicSplitPaneUI extends SplitPaneUI * Keys to use for forward focus traversal when the JComponent is * managing focus. */ - private static Set managingFocusForwardTraversalKeys; + private Set managingFocusForwardTraversalKeys; /** * Keys to use for backward focus traversal when the JComponent is * managing focus. */ - private static Set managingFocusBackwardTraversalKeys; + private Set managingFocusBackwardTraversalKeys; /** @@ -675,7 +673,7 @@ public class BasicSplitPaneUI extends SplitPaneUI * @return increment via keyboard methods. */ int getKeyboardMoveIncrement() { - return KEYBOARD_DIVIDER_MOVE_OFFSET; + return 3; } /** diff --git a/jdk/src/share/classes/javax/swing/plaf/metal/MetalBumps.java b/jdk/src/share/classes/javax/swing/plaf/metal/MetalBumps.java index 655393b43fd..ae3ad679121 100644 --- a/jdk/src/share/classes/javax/swing/plaf/metal/MetalBumps.java +++ b/jdk/src/share/classes/javax/swing/plaf/metal/MetalBumps.java @@ -1,5 +1,5 @@ /* - * Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1998-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 @@ -28,8 +28,9 @@ package javax.swing.plaf.metal; import java.awt.*; import java.awt.image.*; import javax.swing.*; -import java.io.*; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import sun.awt.AppContext; /** * Implements the bumps used throughout the Metal Look and Feel. @@ -49,19 +50,9 @@ class MetalBumps implements Icon { protected Color shadowColor; protected Color backColor; - protected static Vector buffers = new Vector(); + private static final Object METAL_BUMPS = new Object(); protected BumpBuffer buffer; - public MetalBumps( Dimension bumpArea ) { - this( bumpArea.width, bumpArea.height ); - } - - public MetalBumps( int width, int height ) { - this(width, height, MetalLookAndFeel.getPrimaryControlHighlight(), - MetalLookAndFeel.getPrimaryControlDarkShadow(), - MetalLookAndFeel.getPrimaryControlShadow()); - } - /** * Creates MetalBumps of the specified size with the specified colors. * If newBackColor is null, the background will be @@ -73,26 +64,22 @@ class MetalBumps implements Icon { setBumpColors( newTopColor, newShadowColor, newBackColor ); } - private BumpBuffer getBuffer(GraphicsConfiguration gc, Color aTopColor, - Color aShadowColor, Color aBackColor) { - if (buffer != null && buffer.hasSameConfiguration( - gc, aTopColor, aShadowColor, aBackColor)) { - return buffer; + private static BumpBuffer createBuffer(GraphicsConfiguration gc, + Color topColor, Color shadowColor, Color backColor) { + AppContext context = AppContext.getAppContext(); + List buffers = (List) context.get(METAL_BUMPS); + if (buffers == null) { + buffers = new ArrayList(); + context.put(METAL_BUMPS, buffers); } - BumpBuffer result = null; - - for (BumpBuffer aBuffer : buffers) { - if ( aBuffer.hasSameConfiguration(gc, aTopColor, aShadowColor, - aBackColor)) { - result = aBuffer; - break; + for (BumpBuffer buffer : buffers) { + if (buffer.hasSameConfiguration(gc, topColor, shadowColor, backColor)) { + return buffer; } } - if (result == null) { - result = new BumpBuffer(gc, topColor, shadowColor, backColor); - buffers.addElement(result); - } - return result; + BumpBuffer buffer = new BumpBuffer(gc, topColor, shadowColor, backColor); + buffers.add(buffer); + return buffer; } public void setBumpArea( Dimension bumpArea ) { @@ -119,10 +106,12 @@ class MetalBumps implements Icon { GraphicsConfiguration gc = (g instanceof Graphics2D) ? ((Graphics2D) g).getDeviceConfiguration() : null; - buffer = getBuffer(gc, topColor, shadowColor, backColor); + if ((buffer == null) || !buffer.hasSameConfiguration(gc, topColor, shadowColor, backColor)) { + buffer = createBuffer(gc, topColor, shadowColor, backColor); + } - int bufferWidth = buffer.getImageSize().width; - int bufferHeight = buffer.getImageSize().height; + int bufferWidth = BumpBuffer.IMAGE_SIZE; + int bufferHeight = BumpBuffer.IMAGE_SIZE; int iconWidth = getIconWidth(); int iconHeight = getIconHeight(); int x2 = x + iconWidth; @@ -155,7 +144,6 @@ class MetalBumps implements Icon { class BumpBuffer { static final int IMAGE_SIZE = 64; - static Dimension imageSize = new Dimension( IMAGE_SIZE, IMAGE_SIZE ); transient Image image; Color topColor; @@ -197,10 +185,6 @@ class BumpBuffer { return image; } - public Dimension getImageSize() { - return imageSize; - } - /** * Paints the bumps into the current image. */ diff --git a/jdk/src/share/classes/javax/swing/plaf/metal/MetalInternalFrameUI.java b/jdk/src/share/classes/javax/swing/plaf/metal/MetalInternalFrameUI.java index d960ca19b75..adac940c4a4 100644 --- a/jdk/src/share/classes/javax/swing/plaf/metal/MetalInternalFrameUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/metal/MetalInternalFrameUI.java @@ -1,5 +1,5 @@ /* - * Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1998-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 @@ -31,10 +31,8 @@ import javax.swing.*; import javax.swing.event.*; import javax.swing.border.*; import javax.swing.plaf.basic.*; -import java.util.EventListener; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeEvent; -import java.beans.PropertyVetoException; import javax.swing.plaf.*; /** @@ -51,7 +49,7 @@ public class MetalInternalFrameUI extends BasicInternalFrameUI { private static final Border handyEmptyBorder = new EmptyBorder(0,0,0,0); protected static String IS_PALETTE = "JInternalFrame.isPalette"; - + private static String IS_PALETTE_KEY = "JInternalFrame.isPalette"; private static String FRAME_TYPE = "JInternalFrame.frameType"; private static String NORMAL_FRAME = "normal"; private static String PALETTE_FRAME = "palette"; @@ -68,7 +66,7 @@ public class MetalInternalFrameUI extends BasicInternalFrameUI { public void installUI(JComponent c) { super.installUI(c); - Object paletteProp = c.getClientProperty( IS_PALETTE ); + Object paletteProp = c.getClientProperty(IS_PALETTE_KEY); if ( paletteProp != null ) { setPalette( ((Boolean)paletteProp).booleanValue() ); } @@ -187,7 +185,7 @@ public class MetalInternalFrameUI extends BasicInternalFrameUI { ui.setFrameType( (String) e.getNewValue() ); } } - else if ( name.equals( IS_PALETTE ) ) + else if ( name.equals(IS_PALETTE_KEY) ) { if ( e.getNewValue() != null ) { diff --git a/jdk/src/share/classes/javax/swing/plaf/metal/MetalSliderUI.java b/jdk/src/share/classes/javax/swing/plaf/metal/MetalSliderUI.java index 28d22705b16..da3d424e409 100644 --- a/jdk/src/share/classes/javax/swing/plaf/metal/MetalSliderUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/metal/MetalSliderUI.java @@ -1,5 +1,5 @@ /* - * Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1998-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 @@ -54,12 +54,13 @@ public class MetalSliderUI extends BasicSliderUI { protected final int TICK_BUFFER = 4; protected boolean filledSlider = false; - // NOTE: these next three variables are currently unused. + // NOTE: these next five variables are currently unused. protected static Color thumbColor; protected static Color highlightColor; protected static Color darkShadowColor; protected static int trackWidth; protected static int tickLength; + private int safeLength; /** * A default horizontal thumb Icon. This field might not be @@ -107,7 +108,7 @@ public class MetalSliderUI extends BasicSliderUI { public void installUI( JComponent c ) { trackWidth = ((Integer)UIManager.get( "Slider.trackWidth" )).intValue(); - tickLength = ((Integer)UIManager.get( "Slider.majorTickLength" )).intValue(); + tickLength = safeLength = ((Integer)UIManager.get( "Slider.majorTickLength" )).intValue(); horizThumbIcon = SAFE_HORIZ_THUMB_ICON = UIManager.getIcon( "Slider.horizontalThumbIcon" ); vertThumbIcon = SAFE_VERT_THUMB_ICON = @@ -477,8 +478,8 @@ public class MetalSliderUI extends BasicSliderUI { * determine the tick area rectangle. */ public int getTickLength() { - return slider.getOrientation() == JSlider.HORIZONTAL ? tickLength + TICK_BUFFER + 1 : - tickLength + TICK_BUFFER + 3; + return slider.getOrientation() == JSlider.HORIZONTAL ? safeLength + TICK_BUFFER + 1 : + safeLength + TICK_BUFFER + 3; } /** @@ -523,22 +524,22 @@ public class MetalSliderUI extends BasicSliderUI { protected void paintMinorTickForHorizSlider( Graphics g, Rectangle tickBounds, int x ) { g.setColor( slider.isEnabled() ? slider.getForeground() : MetalLookAndFeel.getControlShadow() ); - g.drawLine( x, TICK_BUFFER, x, TICK_BUFFER + (tickLength / 2) ); + g.drawLine( x, TICK_BUFFER, x, TICK_BUFFER + (safeLength / 2) ); } protected void paintMajorTickForHorizSlider( Graphics g, Rectangle tickBounds, int x ) { g.setColor( slider.isEnabled() ? slider.getForeground() : MetalLookAndFeel.getControlShadow() ); - g.drawLine( x, TICK_BUFFER , x, TICK_BUFFER + (tickLength - 1) ); + g.drawLine( x, TICK_BUFFER , x, TICK_BUFFER + (safeLength - 1) ); } protected void paintMinorTickForVertSlider( Graphics g, Rectangle tickBounds, int y ) { g.setColor( slider.isEnabled() ? slider.getForeground() : MetalLookAndFeel.getControlShadow() ); if (MetalUtils.isLeftToRight(slider)) { - g.drawLine( TICK_BUFFER, y, TICK_BUFFER + (tickLength / 2), y ); + g.drawLine( TICK_BUFFER, y, TICK_BUFFER + (safeLength / 2), y ); } else { - g.drawLine( 0, y, tickLength/2, y ); + g.drawLine( 0, y, safeLength/2, y ); } } @@ -546,10 +547,10 @@ public class MetalSliderUI extends BasicSliderUI { g.setColor( slider.isEnabled() ? slider.getForeground() : MetalLookAndFeel.getControlShadow() ); if (MetalUtils.isLeftToRight(slider)) { - g.drawLine( TICK_BUFFER, y, TICK_BUFFER + tickLength, y ); + g.drawLine( TICK_BUFFER, y, TICK_BUFFER + safeLength, y ); } else { - g.drawLine( 0, y, tickLength, y ); + g.drawLine( 0, y, safeLength, y ); } } } diff --git a/jdk/test/javax/swing/ToolTipManager/Test6657026.java b/jdk/test/javax/swing/ToolTipManager/Test6657026.java new file mode 100644 index 00000000000..f9e23b988bb --- /dev/null +++ b/jdk/test/javax/swing/ToolTipManager/Test6657026.java @@ -0,0 +1,74 @@ +/* + * 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 6657026 + * @summary Tests shared ToolTipManager in different application contexts + * @author Sergey Malenkov + */ + +import sun.awt.SunToolkit; +import javax.swing.ToolTipManager; + +public class Test6657026 implements Runnable { + + private static final int DISMISS = 4000; + private static final int INITIAL = 750; + private static final int RESHOW = 500; + + public static void main(String[] args) throws InterruptedException { + ToolTipManager manager = ToolTipManager.sharedInstance(); + if (DISMISS != manager.getDismissDelay()) { + throw new Error("unexpected dismiss delay"); + } + if (INITIAL != manager.getInitialDelay()) { + throw new Error("unexpected initial delay"); + } + if (RESHOW != manager.getReshowDelay()) { + throw new Error("unexpected reshow delay"); + } + manager.setDismissDelay(DISMISS + 1); + manager.setInitialDelay(INITIAL + 1); + manager.setReshowDelay(RESHOW + 1); + + ThreadGroup group = new ThreadGroup("$$$"); + Thread thread = new Thread(group, new Test6657026()); + thread.start(); + thread.join(); + } + + public void run() { + SunToolkit.createNewAppContext(); + ToolTipManager manager = ToolTipManager.sharedInstance(); + if (DISMISS != manager.getDismissDelay()) { + throw new Error("shared dismiss delay"); + } + if (INITIAL != manager.getInitialDelay()) { + throw new Error("shared initial delay"); + } + if (RESHOW != manager.getReshowDelay()) { + throw new Error("shared reshow delay"); + } + } +} diff --git a/jdk/test/javax/swing/UIManager/Test6657026.java b/jdk/test/javax/swing/UIManager/Test6657026.java new file mode 100644 index 00000000000..7b93a22196c --- /dev/null +++ b/jdk/test/javax/swing/UIManager/Test6657026.java @@ -0,0 +1,59 @@ +/* + * 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 6657026 + * @summary Tests shared UIManager in different application contexts + * @author Sergey Malenkov + */ + +import sun.awt.SunToolkit; + +import javax.swing.UIManager; +import javax.swing.UIManager.LookAndFeelInfo; + +public class Test6657026 implements Runnable { + + public static void main(String[] args) throws Exception { + if (UIManager.getInstalledLookAndFeels().length == 0) { + throw new Error("unexpected amount of look&feels"); + } + UIManager.setInstalledLookAndFeels(new LookAndFeelInfo[0]); + if (UIManager.getInstalledLookAndFeels().length != 0) { + throw new Error("unexpected amount of look&feels"); + } + + ThreadGroup group = new ThreadGroup("$$$"); + Thread thread = new Thread(group, new Test6657026()); + thread.start(); + thread.join(); + } + + public void run() { + SunToolkit.createNewAppContext(); + if (UIManager.getInstalledLookAndFeels().length == 0) { + throw new Error("shared look&feels"); + } + } +} diff --git a/jdk/test/javax/swing/plaf/basic/BasicSplitPaneUI/Test6657026.java b/jdk/test/javax/swing/plaf/basic/BasicSplitPaneUI/Test6657026.java new file mode 100644 index 00000000000..16080416f73 --- /dev/null +++ b/jdk/test/javax/swing/plaf/basic/BasicSplitPaneUI/Test6657026.java @@ -0,0 +1,82 @@ +/* + * 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 6657026 + * @summary Tests shared BasicSplitPaneUI in different application contexts + * @author Sergey Malenkov + */ + +import sun.awt.SunToolkit; + +import java.awt.event.ActionEvent; +import java.util.Set; +import javax.swing.JSplitPane; +import javax.swing.plaf.basic.BasicSplitPaneUI; + +public class Test6657026 extends BasicSplitPaneUI implements Runnable { + + public static void main(String[] args) throws InterruptedException { + if (new JSplitPane().getFocusTraversalKeys(0).isEmpty()){ + throw new Error("unexpected traversal keys"); + } + new JSplitPane() { + public void setFocusTraversalKeys(int id, Set keystrokes) { + keystrokes.clear(); + super.setFocusTraversalKeys(id, keystrokes); + } + }; + if (new JSplitPane().getFocusTraversalKeys(0).isEmpty()) { + throw new Error("shared traversal keys"); + } + KEYBOARD_DIVIDER_MOVE_OFFSET = -KEYBOARD_DIVIDER_MOVE_OFFSET; + + ThreadGroup group = new ThreadGroup("$$$"); + Thread thread = new Thread(group, new Test6657026()); + thread.start(); + thread.join(); + } + + public void run() { + SunToolkit.createNewAppContext(); + if (new JSplitPane().getFocusTraversalKeys(0).isEmpty()) { + throw new Error("shared traversal keys"); + } + JSplitPane pane = new JSplitPane(); + pane.setUI(this); + + createFocusListener().focusGained(null); // allows actions + test(pane, "positiveIncrement", 3); + test(pane, "negativeIncrement", 0); + } + + private static void test(JSplitPane pane, String action, int expected) { + ActionEvent event = new ActionEvent(pane, expected, action); + pane.getActionMap().get(action).actionPerformed(event); + int actual = pane.getDividerLocation(); + if (actual != expected) { + throw new Error(actual + ", but expected " + expected); + } + } +} diff --git a/jdk/test/javax/swing/plaf/metal/MetalBorders/Test6657026.java b/jdk/test/javax/swing/plaf/metal/MetalBorders/Test6657026.java new file mode 100644 index 00000000000..194b310f450 --- /dev/null +++ b/jdk/test/javax/swing/plaf/metal/MetalBorders/Test6657026.java @@ -0,0 +1,91 @@ +/* + * 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 6657026 + * @summary Tests constancy of borders + * @author Sergey Malenkov + */ + +import java.awt.Insets; +import javax.swing.border.Border; +import javax.swing.plaf.metal.MetalBorders.ButtonBorder; +import javax.swing.plaf.metal.MetalBorders.MenuBarBorder; +import javax.swing.plaf.metal.MetalBorders.MenuItemBorder; +import javax.swing.plaf.metal.MetalBorders.PopupMenuBorder; + +public class Test6657026 { + + private static final Insets NEGATIVE = new Insets(Integer.MIN_VALUE, + Integer.MIN_VALUE, + Integer.MIN_VALUE, + Integer.MIN_VALUE); + + public static void main(String[] args) { + new ButtonBorder() {{borderInsets = NEGATIVE;}}; + new MenuBarBorder() {{borderInsets = NEGATIVE;}}; + new MenuItemBorder() {{borderInsets = NEGATIVE;}}; + new PopupMenuBorder() {{borderInsets = NEGATIVE;}}; + + test(create("ButtonBorder")); + test(create("MenuBarBorder")); + test(create("MenuItemBorder")); + test(create("PopupMenuBorder")); + + test(create("Flush3DBorder")); + test(create("InternalFrameBorder")); + // NOT USED: test(create("FrameBorder")); + // NOT USED: test(create("DialogBorder")); + test(create("PaletteBorder")); + test(create("OptionDialogBorder")); + test(create("ScrollPaneBorder")); + } + + private static Border create(String name) { + try { + name = "javax.swing.plaf.metal.MetalBorders$" + name; + return (Border) Class.forName(name).newInstance(); + } + catch (Exception exception) { + throw new Error("unexpected exception", exception); + } + } + + private static void test(Border border) { + Insets actual = border.getBorderInsets(null); + if (NEGATIVE.equals(actual)) { + throw new Error("unexpected insets in " + border.getClass()); + } + Insets expected = (Insets) actual.clone(); + // modify + actual.top++; + actual.left++; + actual.right++; + actual.bottom++; + // validate + if (!expected.equals(border.getBorderInsets(null))) { + throw new Error("shared insets in " + border.getClass()); + } + } +} diff --git a/jdk/test/javax/swing/plaf/metal/MetalBumps/Test6657026.java b/jdk/test/javax/swing/plaf/metal/MetalBumps/Test6657026.java new file mode 100644 index 00000000000..f8041629346 --- /dev/null +++ b/jdk/test/javax/swing/plaf/metal/MetalBumps/Test6657026.java @@ -0,0 +1,238 @@ +/* + * 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 6657026 + * @summary Tests shared MetalBumps in different application contexts + * @author Sergey Malenkov + */ + +import sun.awt.SunToolkit; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.Rectangle; +import java.awt.Shape; +import java.awt.image.BufferedImage; +import java.awt.image.ImageObserver; +import java.text.AttributedCharacterIterator; +import javax.swing.Icon; +import javax.swing.plaf.metal.MetalBorders.ToolBarBorder; + +public class Test6657026 extends ToolBarBorder implements Runnable { + + public static void main(String[] args) throws Exception { + new Test6657026().test(); + + ThreadGroup group = new ThreadGroup("$$$"); + Thread thread = new Thread(group, new Test6657026()); + thread.start(); + thread.join(); + } + + public void run() { + SunToolkit.createNewAppContext(); + test(); + } + + private void test() { + MyGraphics mg = new MyGraphics(); + Icon icon = bumps; + icon.paintIcon(mg.component, mg, 0, 0); + if (mg.image != null) { + boolean failed = true; + int value = mg.image.getRGB(0, 0); + for (int x = 0; x < mg.image.getWidth(); x++) { + for (int y = 0; y < mg.image.getHeight(); y++) { + int current = mg.image.getRGB(x, y); + if (current != value) { + mg.image.setRGB(x, y, value); + failed = false; + } + + } + } + if (failed) { + throw new Error("shared metal bumps"); + } + } + } + + private static class MyGraphics extends Graphics { + + private final Component component = new Component() {}; + private BufferedImage image; + + public Graphics create() { + return null; // TODO: check + } + + public void translate(int x, int y) { + // TODO: check + } + + public Color getColor() { + return null; // TODO: check + } + + public void setColor(Color color) { + // TODO: check + } + + public void setPaintMode() { + // TODO: check + } + + public void setXORMode(Color c1) { + // TODO: check + } + + public Font getFont() { + return null; // TODO: check + } + + public void setFont(Font font) { + // TODO: check + } + + public FontMetrics getFontMetrics(Font font) { + return null; // TODO: check + } + + public Rectangle getClipBounds() { + return null; // TODO: check + } + + public void clipRect(int x, int y, int width, int height) { + // TODO: check + } + + public void setClip(int x, int y, int width, int height) { + // TODO: check + } + + public Shape getClip() { + return null; // TODO: check + } + + public void setClip(Shape clip) { + // TODO: check + } + + public void copyArea(int x, int y, int width, int height, int dx, int dy) { + // TODO: check + } + + public void drawLine(int x1, int y1, int x2, int y2) { + // TODO: check + } + + public void fillRect(int x, int y, int width, int height) { + // TODO: check + } + + public void clearRect(int x, int y, int width, int height) { + // TODO: check + } + + public void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) { + // TODO: check + } + + public void fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) { + // TODO: check + } + + public void drawOval(int x, int y, int width, int height) { + // TODO: check + } + + public void fillOval(int x, int y, int width, int height) { + // TODO: check + } + + public void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle) { + // TODO: check + } + + public void fillArc(int x, int y, int width, int height, int startAngle, int arcAngle) { + // TODO: check + } + + public void drawPolyline(int[] xPoints, int[] yPoints, int nPoints) { + // TODO: check + } + + public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints) { + // TODO: check + } + + public void fillPolygon(int[] xPoints, int[] yPoints, int nPoints) { + // TODO: check + } + + public void drawString(String str, int x, int y) { + // TODO: check + } + + public void drawString(AttributedCharacterIterator iterator, int x, int y) { + // TODO: check + } + + public boolean drawImage(Image img, int x, int y, ImageObserver observer) { + return false; // TODO: check + } + + public boolean drawImage(Image img, int x, int y, int width, int height, ImageObserver observer) { + return false; // TODO: check + } + + public boolean drawImage(Image img, int x, int y, Color bgcolor, ImageObserver observer) { + return false; // TODO: check + } + + public boolean drawImage(Image img, int x, int y, int width, int height, Color bgcolor, ImageObserver observer) { + return false; // TODO: check + } + + public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver observer) { + if (img instanceof BufferedImage) { + this.image = (BufferedImage) img; + } + return false; // TODO: check + } + + public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, Color bgcolor, ImageObserver observer) { + return false; // TODO: check + } + + public void dispose() { + // TODO: check + } + } +} diff --git a/jdk/test/javax/swing/plaf/metal/MetalInternalFrameUI/Test6657026.java b/jdk/test/javax/swing/plaf/metal/MetalInternalFrameUI/Test6657026.java new file mode 100644 index 00000000000..bbfec61c5ba --- /dev/null +++ b/jdk/test/javax/swing/plaf/metal/MetalInternalFrameUI/Test6657026.java @@ -0,0 +1,60 @@ +/* + * 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 6657026 + * @summary Tests shared MetalInternalFrameUI in different application contexts + * @author Sergey Malenkov + */ + +import sun.awt.SunToolkit; + +import javax.swing.JInternalFrame; +import javax.swing.JPanel; +import javax.swing.UIManager; +import javax.swing.plaf.metal.MetalInternalFrameUI; +import javax.swing.plaf.metal.MetalLookAndFeel; + +public class Test6657026 extends MetalInternalFrameUI implements Runnable { + + public static void main(String[] args) throws Exception { + UIManager.setLookAndFeel(new MetalLookAndFeel()); + + ThreadGroup group = new ThreadGroup("$$$"); + Thread thread = new Thread(group, new Test6657026()); + thread.start(); + thread.join(); + + new JInternalFrame().setContentPane(new JPanel()); + } + + public Test6657026() { + super(null); + } + + public void run() { + SunToolkit.createNewAppContext(); + IS_PALETTE = JInternalFrame.CONTENT_PANE_PROPERTY; + } +} diff --git a/jdk/test/javax/swing/plaf/metal/MetalSliderUI/Test6657026.java b/jdk/test/javax/swing/plaf/metal/MetalSliderUI/Test6657026.java new file mode 100644 index 00000000000..250889acd89 --- /dev/null +++ b/jdk/test/javax/swing/plaf/metal/MetalSliderUI/Test6657026.java @@ -0,0 +1,67 @@ +/* + * 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 6657026 + * @summary Tests shared MetalSliderUI in different application contexts + * @author Sergey Malenkov + */ + +import sun.awt.SunToolkit; + +import javax.swing.JSlider; +import javax.swing.UIManager; +import javax.swing.plaf.metal.MetalLookAndFeel; +import javax.swing.plaf.metal.MetalSliderUI; + +public class Test6657026 extends MetalSliderUI implements Runnable { + + public static void main(String[] args) throws Exception { + UIManager.setLookAndFeel(new MetalLookAndFeel()); + JSlider slider = new JSlider(); + test(slider); + + ThreadGroup group = new ThreadGroup("$$$"); + Thread thread = new Thread(group, new Test6657026()); + thread.start(); + thread.join(); + + test(slider); + } + + public void run() { + SunToolkit.createNewAppContext(); + JSlider slider = new JSlider(); + test(slider); + tickLength = -10000; + } + + private static void test(JSlider slider) { + MetalSliderUI ui = (MetalSliderUI) slider.getUI(); + int actual = ui.getTickLength(); + if (actual != 11) { + throw new Error(actual + ", but expected 11"); + } + } +}