Merge
authoryan
Wed, 29 Jul 2009 00:14:56 -0700
changeset 3351 478ff4c1be9b
parent 3339 92dc2068efc2 (current diff)
parent 3350 100ac73bfe6e (diff)
child 3352 a6d1fd7195a2
Merge
jdk/src/share/classes/javax/swing/plaf/basic/DesktopIconMover.java
--- a/jdk/src/share/classes/javax/swing/JFileChooser.java	Wed Jul 29 00:12:45 2009 -0700
+++ b/jdk/src/share/classes/javax/swing/JFileChooser.java	Wed Jul 29 00:14:56 2009 -0700
@@ -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
@@ -739,6 +739,11 @@
 
         dialog.show();
         firePropertyChange("JFileChooserDialogIsClosingProperty", dialog, null);
+
+        // Remove all components from dialog. The MetalFileChooserUI.installUI() method (and other LAFs)
+        // registers AWT listener for dialogs and produces memory leaks. It happens when
+        // installUI invoked after the showDialog method.
+        dialog.getContentPane().removeAll();
         dialog.dispose();
         dialog = null;
         return returnValue;
--- a/jdk/src/share/classes/javax/swing/JInternalFrame.java	Wed Jul 29 00:12:45 2009 -0700
+++ b/jdk/src/share/classes/javax/swing/JInternalFrame.java	Wed Jul 29 00:14:56 2009 -0700
@@ -26,13 +26,10 @@
 package javax.swing;
 
 import java.awt.*;
-import java.awt.event.*;
 
 import java.beans.PropertyVetoException;
 import java.beans.PropertyChangeEvent;
-import java.util.EventListener;
 
-import javax.swing.border.Border;
 import javax.swing.event.InternalFrameEvent;
 import javax.swing.event.InternalFrameListener;
 import javax.swing.plaf.*;
@@ -40,7 +37,6 @@
 import javax.accessibility.*;
 
 import java.io.ObjectOutputStream;
-import java.io.ObjectInputStream;
 import java.io.IOException;
 import java.lang.StringBuilder;
 import java.beans.PropertyChangeListener;
@@ -1459,19 +1455,22 @@
             SwingUtilities2.compositeRequestFocus(getDesktopIcon());
         }
         else {
-            // FocusPropertyChangeListener will eventually update
-            // lastFocusOwner. As focus requests are asynchronous
-            // lastFocusOwner may be accessed before it has been correctly
-            // updated. To avoid any problems, lastFocusOwner is immediately
-            // set, assuming the request will succeed.
-            lastFocusOwner = getMostRecentFocusOwner();
-            if (lastFocusOwner == null) {
-                // Make sure focus is restored somewhere, so that
-                // we don't leave a focused component in another frame while
-                // this frame is selected.
-                lastFocusOwner = getContentPane();
+            Component component = KeyboardFocusManager.getCurrentKeyboardFocusManager().getPermanentFocusOwner();
+            if ((component == null) || !SwingUtilities.isDescendingFrom(component, this)) {
+                // FocusPropertyChangeListener will eventually update
+                // lastFocusOwner. As focus requests are asynchronous
+                // lastFocusOwner may be accessed before it has been correctly
+                // updated. To avoid any problems, lastFocusOwner is immediately
+                // set, assuming the request will succeed.
+                setLastFocusOwner(getMostRecentFocusOwner());
+                if (lastFocusOwner == null) {
+                    // Make sure focus is restored somewhere, so that
+                    // we don't leave a focused component in another frame while
+                    // this frame is selected.
+                    setLastFocusOwner(getContentPane());
+                }
+                lastFocusOwner.requestFocus();
             }
-            lastFocusOwner.requestFocus();
         }
     }
 
--- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicDesktopIconUI.java	Wed Jul 29 00:12:45 2009 -0700
+++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicDesktopIconUI.java	Wed Jul 29 00:14:56 2009 -0700
@@ -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
@@ -32,9 +32,6 @@
 import javax.swing.border.*;
 import javax.swing.plaf.*;
 import java.beans.*;
-import java.util.EventListener;
-import java.io.Serializable;
-
 
 /**
  * Basic L&F for a minimized window on a desktop.
@@ -47,7 +44,6 @@
 
     protected JInternalFrame.JDesktopIcon desktopIcon;
     protected JInternalFrame frame;
-    private DesktopIconMover desktopIconMover;
 
     /**
      * The title pane component used in the desktop icon.
@@ -128,21 +124,12 @@
         mouseInputListener = createMouseInputListener();
         desktopIcon.addMouseMotionListener(mouseInputListener);
         desktopIcon.addMouseListener(mouseInputListener);
-         getDesktopIconMover().installListeners();
     }
 
     protected void uninstallListeners() {
         desktopIcon.removeMouseMotionListener(mouseInputListener);
         desktopIcon.removeMouseListener(mouseInputListener);
         mouseInputListener = null;
-         getDesktopIconMover().uninstallListeners();
-    }
-
-    private DesktopIconMover getDesktopIconMover() {
-        if (desktopIconMover == null) {
-            desktopIconMover = new DesktopIconMover(desktopIcon);
-        }
-        return desktopIconMover;
     }
 
     protected void installDefaults() {
--- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicDirectoryModel.java	Wed Jul 29 00:12:45 2009 -0700
+++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicDirectoryModel.java	Wed Jul 29 00:14:56 2009 -0700
@@ -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
@@ -232,6 +232,10 @@
         public void run0() {
             FileSystemView fileSystem = filechooser.getFileSystemView();
 
+            if (isInterrupted()) {
+                return;
+            }
+
             File[] list = fileSystem.getFiles(currentDirectory, filechooser.isFileHidingEnabled());
 
             if (isInterrupted()) {
@@ -268,8 +272,8 @@
 
             // To avoid loads of synchronizations with Invoker and improve performance we
             // execute the whole block on the COM thread
-            DoChangeContents doChangeContents = ShellFolder.getInvoker().invoke(new Callable<DoChangeContents>() {
-                public DoChangeContents call() throws Exception {
+            DoChangeContents doChangeContents = ShellFolder.invoke(new Callable<DoChangeContents>() {
+                public DoChangeContents call() {
                     int newSize = newFileCache.size();
                     int oldSize = fileCache.size();
 
--- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicInternalFrameUI.java	Wed Jul 29 00:12:45 2009 -0700
+++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicInternalFrameUI.java	Wed Jul 29 00:14:56 2009 -0700
@@ -27,16 +27,10 @@
 
 import java.awt.*;
 import java.awt.event.*;
-import java.awt.peer.LightweightPeer;
-
 import javax.swing.*;
-import javax.swing.border.*;
 import javax.swing.plaf.*;
 import javax.swing.event.*;
-
 import java.beans.*;
-import java.io.Serializable;
-
 import sun.swing.DefaultLookup;
 import sun.swing.UIAction;
 
@@ -55,6 +49,7 @@
     protected MouseInputAdapter          borderListener;
     protected PropertyChangeListener     propertyChangeListener;
     protected LayoutManager              internalFrameLayout;
+    protected ComponentListener          componentListener;
     protected MouseInputListener         glassPaneDispatcher;
     private InternalFrameListener        internalFrameListener;
 
@@ -66,9 +61,9 @@
     protected BasicInternalFrameTitlePane titlePane; // access needs this
 
     private static DesktopManager sharedDesktopManager;
+    private boolean componentListenerAdded = false;
 
     private Rectangle parentBounds;
-    private DesktopIconMover desktopIconMover;
 
     private boolean dragging = false;
     private boolean resizing = false;
@@ -209,17 +204,14 @@
             frame.getGlassPane().addMouseListener(glassPaneDispatcher);
             frame.getGlassPane().addMouseMotionListener(glassPaneDispatcher);
         }
+        componentListener =  createComponentListener();
         if (frame.getParent() != null) {
           parentBounds = frame.getParent().getBounds();
         }
-        getDesktopIconMover().installListeners();
-    }
-
-    private DesktopIconMover getDesktopIconMover() {
-        if (desktopIconMover == null) {
-            desktopIconMover = new DesktopIconMover(frame);
+        if ((frame.getParent() != null) && !componentListenerAdded) {
+            frame.getParent().addComponentListener(componentListener);
+            componentListenerAdded = true;
         }
-        return desktopIconMover;
     }
 
     // Provide a FocusListener to listen for a WINDOW_LOST_FOCUS event,
@@ -290,7 +282,11 @@
      * @since 1.3
      */
     protected void uninstallListeners() {
-      getDesktopIconMover().uninstallListeners();
+        if ((frame.getParent() != null) && componentListenerAdded) {
+            frame.getParent().removeComponentListener(componentListener);
+            componentListenerAdded = false;
+        }
+        componentListener = null;
       if (glassPaneDispatcher != null) {
           frame.getGlassPane().removeMouseListener(glassPaneDispatcher);
           frame.getGlassPane().removeMouseMotionListener(glassPaneDispatcher);
@@ -1228,6 +1224,15 @@
                 }
             }
 
+            // Relocate the icon base on the new parent bounds.
+            if (icon != null) {
+                Rectangle iconBounds = icon.getBounds();
+                int y = iconBounds.y +
+                        (parentNewBounds.height - parentBounds.height);
+                icon.setBounds(iconBounds.x, y,
+                        iconBounds.width, iconBounds.height);
+            }
+
             // Update the new parent bounds for next resize.
             if (!parentBounds.equals(parentNewBounds)) {
                 parentBounds = parentNewBounds;
@@ -1399,6 +1404,9 @@
                     // Cancel a resize in progress if the internal frame
                     // gets a setClosed(true) or dispose().
                     cancelResize();
+                    if ((frame.getParent() != null) && componentListenerAdded) {
+                        frame.getParent().removeComponentListener(componentListener);
+                    }
                     closeFrame(f);
                 }
             } else if (JInternalFrame.IS_MAXIMUM_PROPERTY == prop) {
@@ -1431,6 +1439,10 @@
                 } else {
                     parentBounds = null;
                 }
+                if ((frame.getParent() != null) && !componentListenerAdded) {
+                    f.getParent().addComponentListener(componentListener);
+                    componentListenerAdded = true;
+                }
             } else if (JInternalFrame.TITLE_PROPERTY == prop ||
                     prop == "closable" || prop == "iconable" ||
                     prop == "maximizable") {
--- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicScrollPaneUI.java	Wed Jul 29 00:12:45 2009 -0700
+++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicScrollPaneUI.java	Wed Jul 29 00:14:56 2009 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2005 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
@@ -37,17 +37,12 @@
 import java.beans.PropertyChangeEvent;
 
 import java.awt.Component;
-import java.awt.Container;
-import java.awt.LayoutManager;
 import java.awt.Rectangle;
 import java.awt.Dimension;
 import java.awt.Point;
 import java.awt.Insets;
 import java.awt.Graphics;
 import java.awt.event.*;
-import java.io.Serializable;
-import java.awt.Toolkit;
-import java.awt.ComponentOrientation;
 
 /**
  * A default L&F implementation of ScrollPaneUI.
@@ -63,6 +58,7 @@
     protected ChangeListener viewportChangeListener;
     protected PropertyChangeListener spPropertyChangeListener;
     private MouseWheelListener mouseScrollListener;
+    private int oldExtent = Integer.MIN_VALUE;
 
     /**
      * PropertyChangeListener installed on the vertical scrollbar.
@@ -327,9 +323,13 @@
                             * leave it until someone claims.
                             */
                             value = Math.max(0, Math.min(max - extent, max - extent - viewPosition.x));
+                            if (oldExtent > extent) {
+                                value -= oldExtent - extent;
+                            }
                         }
                     }
                 }
+                oldExtent = extent;
                 hsb.setValues(value, extent, 0, max);
             }
 
@@ -1020,7 +1020,7 @@
 
             if (viewport != null) {
                 if (e.getSource() == viewport) {
-                    viewportStateChanged(e);
+                    syncScrollPaneWithViewport();
                 }
                 else {
                     JScrollBar hsb = scrollpane.getHorizontalScrollBar();
@@ -1077,11 +1077,6 @@
             viewport.setViewPosition(p);
         }
 
-        private void viewportStateChanged(ChangeEvent e) {
-            syncScrollPaneWithViewport();
-        }
-
-
         //
         // PropertyChangeListener: This is installed on both the JScrollPane
         // and the horizontal/vertical scrollbars.
--- a/jdk/src/share/classes/javax/swing/plaf/basic/DesktopIconMover.java	Wed Jul 29 00:12:45 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,168 +0,0 @@
-/*
- * Copyright 1997-2008 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.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun 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 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.
- */
-
-package javax.swing.plaf.basic;
-
-import javax.swing.*;
-import java.awt.*;
-import java.awt.event.*;
-import java.beans.*;
-
-/**
- * DesktopIconMover is intended to move desktop icon
- * when parent window is resized.
- */
-class DesktopIconMover implements ComponentListener, PropertyChangeListener {
-    private Component parent;
-    private JInternalFrame frame; // if not null, DesktopIconMover(frame)
-                                  // constructor was used
-    private JInternalFrame.JDesktopIcon icon;
-    private Rectangle parentBounds;
-    private boolean componentListenerAdded = false;
-
-    public DesktopIconMover(JInternalFrame frame) {
-        if (frame == null) {
-            throw new NullPointerException("Frame cannot be null");
-        }
-        this.frame = frame;
-        this.icon = frame.getDesktopIcon();
-        if (icon == null) {
-            throw new NullPointerException(
-                    "frame.getDesktopIcon() cannot be null");
-        }
-        this.parent = frame.getParent();
-        if (this.parent != null) {
-            parentBounds = this.parent.getBounds();
-        }
-    }
-
-    public DesktopIconMover(JInternalFrame.JDesktopIcon icon) {
-        if (icon == null) {
-            throw new NullPointerException("Icon cannot be null");
-        }
-        this.icon = icon;
-        this.parent = icon.getParent();
-        if (this.parent != null) {
-            parentBounds = this.parent.getBounds();
-        }
-    }
-
-    public void installListeners() {
-        if (frame != null) {
-            frame.addPropertyChangeListener(this);
-        } else {
-            icon.addPropertyChangeListener(this);
-        }
-        addComponentListener();
-    }
-
-    public void uninstallListeners() {
-        if (frame != null) {
-            frame.removePropertyChangeListener(this);
-        } else {
-            icon.removePropertyChangeListener(this);
-        }
-        removeComponentListener();
-    }
-
-    public void propertyChange(PropertyChangeEvent evt) {
-        String propName = evt.getPropertyName();
-        if ("ancestor".equals(propName)) {
-            Component newAncestor = (Component) evt.getNewValue();
-
-            // Remove component listener if parent is changing
-            Component probablyNewParent = getCurrentParent();
-            if ((probablyNewParent != null) &&
-                    (!probablyNewParent.equals(parent))) {
-                removeComponentListener();
-                parent = probablyNewParent;
-            }
-
-            if (newAncestor == null) {
-                removeComponentListener();
-            } else {
-                addComponentListener();
-            }
-
-            // Update parentBounds
-            if (parent != null) {
-                parentBounds = parent.getBounds();
-            } else {
-                parentBounds = null;
-            }
-        } else if (JInternalFrame.IS_CLOSED_PROPERTY.equals(propName)) {
-            removeComponentListener();
-        }
-    }
-
-    private void addComponentListener() {
-        if (!componentListenerAdded && (parent != null)) {
-            parent.addComponentListener(this);
-            componentListenerAdded = true;
-        }
-    }
-
-    private void removeComponentListener() {
-        if ((parent != null) && componentListenerAdded) {
-            parent.removeComponentListener(this);
-            componentListenerAdded = false;
-        }
-    }
-
-    private Component getCurrentParent() {
-        if (frame != null) {
-            return frame.getParent();
-        } else {
-            return icon.getParent();
-        }
-    }
-
-    public void componentResized(ComponentEvent e) {
-        if ((parent == null) || (parentBounds == null)) {
-            return;
-        }
-
-        Rectangle parentNewBounds = parent.getBounds();
-        if ((parentNewBounds == null) || parentNewBounds.equals(parentBounds)) {
-            return;
-        }
-
-        // Move desktop icon only in up-down direction
-        int newIconY = icon.getLocation().y +
-                (parentNewBounds.height - parentBounds.height);
-        icon.setLocation(icon.getLocation().x, newIconY);
-
-        parentBounds = parentNewBounds;
-    }
-
-    public void componentMoved(ComponentEvent e) {
-    }
-
-    public void componentShown(ComponentEvent e) {
-    }
-
-    public void componentHidden(ComponentEvent e) {
-    }
-}
--- a/jdk/src/share/classes/javax/swing/plaf/nimbus/AbstractRegionPainter.java	Wed Jul 29 00:12:45 2009 -0700
+++ b/jdk/src/share/classes/javax/swing/plaf/nimbus/AbstractRegionPainter.java	Wed Jul 29 00:14:56 2009 -0700
@@ -227,10 +227,10 @@
      *
      * @param x an encoded x value (0...1, or 1...2, or 2...3)
      * @return the decoded x value
+     * @throws IllegalArgumentException
+     *      if {@code x < 0} or {@code x > 3}
      */
     protected final float decodeX(float x) {
-        if (ctx.canvasSize == null) return x;
-
         if (x >= 0 && x <= 1) {
             return x * leftWidth;
         } else if (x > 1 && x < 2) {
@@ -238,7 +238,7 @@
         } else if (x >= 2 && x <= 3) {
             return ((x-2) * rightWidth) + leftWidth + centerWidth;
         } else {
-            throw new AssertionError("Invalid x");
+            throw new IllegalArgumentException("Invalid x");
         }
     }
 
@@ -248,10 +248,10 @@
      *
      * @param y an encoded y value (0...1, or 1...2, or 2...3)
      * @return the decoded y value
+     * @throws IllegalArgumentException
+     *      if {@code y < 0} or {@code y > 3}
      */
     protected final float decodeY(float y) {
-        if (ctx.canvasSize == null) return y;
-
         if (y >= 0 && y <= 1) {
             return y * topHeight;
         } else if (y > 1 && y < 2) {
@@ -259,7 +259,7 @@
         } else if (y >= 2 && y <= 3) {
             return ((y-2) * bottomHeight) + topHeight + centerHeight;
         } else {
-            throw new AssertionError("Invalid y");
+            throw new IllegalArgumentException("Invalid y");
         }
     }
 
@@ -271,10 +271,10 @@
      * @param x an encoded x value of the bezier control point (0...1, or 1...2, or 2...3)
      * @param dx the offset distance to the anchor from the control point x
      * @return the decoded x location of the control point
+     * @throws IllegalArgumentException
+     *      if {@code x < 0} or {@code x > 3}
      */
     protected final float decodeAnchorX(float x, float dx) {
-        if (ctx.canvasSize == null) return x + dx;
-
         if (x >= 0 && x <= 1) {
             return decodeX(x) + (dx * leftScale);
         } else if (x > 1 && x < 2) {
@@ -282,7 +282,7 @@
         } else if (x >= 2 && x <= 3) {
             return decodeX(x) + (dx * rightScale);
         } else {
-            throw new AssertionError("Invalid x");
+            throw new IllegalArgumentException("Invalid x");
         }
     }
 
@@ -294,10 +294,10 @@
      * @param y an encoded y value of the bezier control point (0...1, or 1...2, or 2...3)
      * @param dy the offset distance to the anchor from the control point y
      * @return the decoded y position of the control point
+     * @throws IllegalArgumentException
+     *      if {@code y < 0} or {@code y > 3}
      */
     protected final float decodeAnchorY(float y, float dy) {
-        if (ctx.canvasSize == null) return y + dy;
-
         if (y >= 0 && y <= 1) {
             return decodeY(y) + (dy * topScale);
         } else if (y > 1 && y < 2) {
@@ -305,7 +305,7 @@
         } else if (y >= 2 && y <= 3) {
             return decodeY(y) + (dy * bottomScale);
         } else {
-            throw new AssertionError("Invalid y");
+            throw new IllegalArgumentException("Invalid y");
         }
     }
 
@@ -363,6 +363,15 @@
      * @param midpoints
      * @param colors
      * @return a valid LinearGradientPaint. This method never returns null.
+     * @throws NullPointerException
+     *      if {@code midpoints} array is null,
+     *      or {@code colors} array is null,
+     * @throws IllegalArgumentException
+     *      if start and end points are the same points,
+     *      or {@code midpoints.length != colors.length},
+     *      or {@code colors} is less than 2 in size,
+     *      or a {@code midpoints} value is less than 0.0 or greater than 1.0,
+     *      or the {@code midpoints} are not provided in strictly increasing order
      */
     protected final LinearGradientPaint decodeGradient(float x1, float y1, float x2, float y2, float[] midpoints, Color[] colors) {
         if (x1 == x2 && y1 == y2) {
@@ -384,6 +393,15 @@
      * @param midpoints
      * @param colors
      * @return a valid RadialGradientPaint. This method never returns null.
+     * @throws NullPointerException
+     *      if {@code midpoints} array is null,
+     *      or {@code colors} array is null
+     * @throws IllegalArgumentException
+     *      if {@code r} is non-positive,
+     *      or {@code midpoints.length != colors.length},
+     *      or {@code colors} is less than 2 in size,
+     *      or a {@code midpoints} value is less than 0.0 or greater than 1.0,
+     *      or the {@code midpoints} are not provided in strictly increasing order
      */
     protected final RadialGradientPaint decodeRadialGradient(float x, float y, float r, float[] midpoints, Color[] colors) {
         if (r == 0f) {
@@ -537,10 +555,10 @@
             this.maxVerticalScaleFactor = maxV;
 
             if (canvasSize != null) {
-                a = insets.left;
-                b = canvasSize.width - insets.right;
-                c = insets.top;
-                d = canvasSize.height - insets.bottom;
+                a = stretchingInsets.left;
+                b = canvasSize.width - stretchingInsets.right;
+                c = stretchingInsets.top;
+                d = canvasSize.height - stretchingInsets.bottom;
                 this.canvasSize = canvasSize;
                 this.inverted = inverted;
                 if (inverted) {
--- a/jdk/src/share/classes/javax/swing/plaf/nimbus/NimbusIcon.java	Wed Jul 29 00:12:45 2009 -0700
+++ b/jdk/src/share/classes/javax/swing/plaf/nimbus/NimbusIcon.java	Wed Jul 29 00:14:56 2009 -0700
@@ -84,6 +84,8 @@
                         translatex = 1;
                     }
                 }
+            } else if (c instanceof JMenu) {
+                flip = ! c.getComponentOrientation().isLeftToRight();
             }
             if (g instanceof Graphics2D){
                 Graphics2D gfx = (Graphics2D)g;
--- a/jdk/src/share/classes/javax/swing/text/GlyphView.java	Wed Jul 29 00:12:45 2009 -0700
+++ b/jdk/src/share/classes/javax/swing/text/GlyphView.java	Wed Jul 29 00:14:56 2009 -0700
@@ -719,8 +719,9 @@
             checkPainter();
             int p0 = getStartOffset();
             int p1 = painter.getBoundedPosition(this, p0, pos, len);
-            return ((p1 > p0) && (getBreakSpot(p0, p1) != BreakIterator.DONE)) ?
-                    View.ExcellentBreakWeight : View.BadBreakWeight;
+            return p1 == p0 ? View.BadBreakWeight :
+                   getBreakSpot(p0, p1) != BreakIterator.DONE ?
+                            View.ExcellentBreakWeight : View.GoodBreakWeight;
         }
         return super.getBreakWeight(axis, pos, len);
     }
--- a/jdk/src/share/classes/javax/swing/text/ParagraphView.java	Wed Jul 29 00:12:45 2009 -0700
+++ b/jdk/src/share/classes/javax/swing/text/ParagraphView.java	Wed Jul 29 00:14:56 2009 -0700
@@ -175,23 +175,6 @@
     }
 
     /**
-     * Adjusts the given row if possible to fit within the
-     * layout span.  By default this will try to find the
-     * highest break weight possible nearest the end of
-     * the row.  If a forced break is encountered, the
-     * break will be positioned there.
-     * <p>
-     * This is meant for internal usage, and should not be used directly.
-     *
-     * @param r the row to adjust to the current layout
-     *          span
-     * @param desiredSpan the current layout span >= 0
-     * @param x the location r starts at
-     */
-    protected void adjustRow(Row r, int desiredSpan, int x) {
-    }
-
-    /**
      * Returns the next visual position for the cursor, in
      * either the east or west direction.
      * Overridden from <code>CompositeView</code>.
--- a/jdk/src/share/classes/sun/awt/shell/ShellFolder.java	Wed Jul 29 00:12:45 2009 -0700
+++ b/jdk/src/share/classes/sun/awt/shell/ShellFolder.java	Wed Jul 29 00:14:56 2009 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-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
@@ -289,8 +289,8 @@
 
         // To avoid loads of synchronizations with Invoker and improve performance we
         // synchronize the whole code of the sort method once
-        getInvoker().invoke(new Callable<Void>() {
-            public Void call() throws Exception {
+        invoke(new Callable<Void>() {
+            public Void call() {
                 // Check that we can use the ShellFolder.sortChildren() method:
                 //   1. All files have the same non-null parent
                 //   2. All files is ShellFolders
@@ -330,8 +330,8 @@
     public void sortChildren(final List<? extends File> files) {
         // To avoid loads of synchronizations with Invoker and improve performance we
         // synchronize the whole code of the sort method once
-        getInvoker().invoke(new Callable<Void>() {
-            public Void call() throws Exception {
+        invoke(new Callable<Void>() {
+            public Void call() {
                 Collections.sort(files, FILE_COMPARATOR);
 
                 return null;
@@ -502,17 +502,61 @@
     }
 
     /**
+     * Invokes the {@code task} which doesn't throw checked exceptions
+     * from its {@code call} method. If invokation is interrupted then Thread.currentThread().isInterrupted() will
+     * be set and result will be {@code null}
+     */
+    public static <T> T invoke(Callable<T> task) {
+        try {
+            return invoke(task, RuntimeException.class);
+        } catch (InterruptedException e) {
+            return null;
+        }
+    }
+
+    /**
+     * Invokes the {@code task} which throws checked exceptions from its {@code call} method.
+     * If invokation is interrupted then Thread.currentThread().isInterrupted() will
+     * be set and InterruptedException will be thrown as well.
+     */
+    public static <T, E extends Throwable> T invoke(Callable<T> task, Class<E> exceptionClass)
+            throws InterruptedException, E {
+        try {
+            return getInvoker().invoke(task);
+        } catch (Exception e) {
+            if (e instanceof RuntimeException) {
+                // Rethrow unchecked exceptions
+                throw (RuntimeException) e;
+            }
+
+            if (e instanceof InterruptedException) {
+                // Set isInterrupted flag for current thread
+                Thread.currentThread().interrupt();
+
+                // Rethrow InterruptedException
+                throw (InterruptedException) e;
+            }
+
+            if (exceptionClass.isInstance(e)) {
+                throw exceptionClass.cast(e);
+            }
+
+            throw new RuntimeException("Unexpected error", e);
+        }
+    }
+
+    /**
      * Interface allowing to invoke tasks in different environments on different platforms.
      */
     public static interface Invoker {
         /**
-         * Invokes a callable task. If the {@code task} throws a checked exception,
-         * it will be wrapped into a {@link RuntimeException}
+         * Invokes a callable task.
          *
          * @param task a task to invoke
+         * @throws Exception {@code InterruptedException} or an exception that was thrown from the {@code task}
          * @return the result of {@code task}'s invokation
          */
-        <T> T invoke(Callable<T> task);
+        <T> T invoke(Callable<T> task) throws Exception;
     }
 
     /**
--- a/jdk/src/share/classes/sun/awt/shell/ShellFolderManager.java	Wed Jul 29 00:12:45 2009 -0700
+++ b/jdk/src/share/classes/sun/awt/shell/ShellFolderManager.java	Wed Jul 29 00:14:56 2009 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-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
@@ -108,12 +108,8 @@
     }
 
     private static class DirectInvoker implements ShellFolder.Invoker {
-        public <T> T invoke(Callable<T> task) {
-            try {
-                return task.call();
-            } catch (Exception e) {
-                throw new RuntimeException(e);
-            }
+        public <T> T invoke(Callable<T> task) throws Exception {
+            return task.call();
         }
     }
 }
--- a/jdk/src/share/classes/sun/swing/FilePane.java	Wed Jul 29 00:12:45 2009 -0700
+++ b/jdk/src/share/classes/sun/swing/FilePane.java	Wed Jul 29 00:14:56 2009 -0700
@@ -1,6 +1,5 @@
-
 /*
- * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2003-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
@@ -905,8 +904,8 @@
 
         @Override
         public void sort() {
-            ShellFolder.getInvoker().invoke(new Callable<Void>() {
-                public Void call() throws Exception {
+            ShellFolder.invoke(new Callable<Void>() {
+                public Void call() {
                     DetailsTableRowSorter.super.sort();
                     return null;
                 }
--- a/jdk/src/share/classes/sun/swing/MenuItemLayoutHelper.java	Wed Jul 29 00:12:45 2009 -0700
+++ b/jdk/src/share/classes/sun/swing/MenuItemLayoutHelper.java	Wed Jul 29 00:14:56 2009 -0700
@@ -718,10 +718,10 @@
     }
 
     private void alignRect(Rectangle rect, int alignment, int origWidth) {
-        if (alignment != SwingUtilities.LEFT) {
+        if (alignment == SwingConstants.RIGHT) {
             rect.x = rect.x + rect.width - origWidth;
-            rect.width = origWidth;
         }
+        rect.width = origWidth;
     }
 
     protected void layoutIconAndTextInLabelRect(LayoutResult lr) {
--- a/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolder2.java	Wed Jul 29 00:12:45 2009 -0700
+++ b/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolder2.java	Wed Jul 29 00:14:56 2009 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2003-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
@@ -29,7 +29,6 @@
 import java.awt.Toolkit;
 import java.awt.image.BufferedImage;
 import java.io.File;
-import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.util.*;
 import java.util.concurrent.*;
@@ -185,8 +184,8 @@
         boolean disposed;
         public void dispose() {
             if (disposed) return;
-            ShellFolder.getInvoker().invoke(new Callable<Void>() {
-                public Void call() throws Exception {
+            invoke(new Callable<Void>() {
+                public Void call() {
                     if (relativePIDL != 0) {
                         releasePIDL(relativePIDL);
                     }
@@ -224,7 +223,7 @@
      */
     private boolean isPersonal;
 
-    private static String composePathForCsidl(int csidl) throws IOException {
+    private static String composePathForCsidl(int csidl) throws IOException, InterruptedException {
         String path = getFileSystemPath(csidl);
         return path == null
                 ? ("ShellFolder: 0x" + Integer.toHexString(csidl))
@@ -235,12 +234,13 @@
      * Create a system special shell folder, such as the
      * desktop or Network Neighborhood.
      */
-    Win32ShellFolder2(final int csidl) throws IOException {
+    Win32ShellFolder2(final int csidl) throws IOException, InterruptedException {
         // Desktop is parent of DRIVES and NETWORK, not necessarily
         // other special shell folders.
         super(null, composePathForCsidl(csidl));
-        ShellFolder.getInvoker().invoke(new Callable<Void>() {
-            public Void call() throws Exception {
+
+        invoke(new Callable<Void>() {
+            public Void call() throws InterruptedException {
                 if (csidl == DESKTOP) {
                     initDesktop();
                 } else {
@@ -276,7 +276,7 @@
                 }
                 return null;
             }
-        });
+        }, InterruptedException.class);
 
         sun.java2d.Disposer.addRecord(this, disposer);
     }
@@ -296,13 +296,13 @@
     /**
      * Creates a shell folder with a parent and relative PIDL
      */
-    Win32ShellFolder2(final Win32ShellFolder2 parent, final long relativePIDL) {
+    Win32ShellFolder2(final Win32ShellFolder2 parent, final long relativePIDL) throws InterruptedException {
         super(parent,
-            ShellFolder.getInvoker().invoke(new Callable<String>() {
-                public String call() throws Exception {
+            invoke(new Callable<String>() {
+                public String call() {
                     return getFileSystemPath(parent.getIShellFolder(), relativePIDL);
                 }
-            })
+            }, RuntimeException.class)
         );
         this.disposer.relativePIDL = relativePIDL;
         getAbsolutePath();
@@ -335,8 +335,8 @@
      * drive (normally "C:\").
      */
     protected Object writeReplace() throws java.io.ObjectStreamException {
-        return ShellFolder.getInvoker().invoke(new Callable<File>() {
-            public File call() throws Exception {
+        return invoke(new Callable<File>() {
+            public File call() {
                 if (isFileSystem()) {
                     return new File(getPath());
                 } else {
@@ -398,11 +398,11 @@
     /**
      * Accessor for IShellFolder
      */
-    public long getIShellFolder() {
+    private long getIShellFolder() {
         if (disposer.pIShellFolder == 0) {
-            disposer.pIShellFolder =
-                ShellFolder.getInvoker().invoke(new Callable<Long>() {
-                    public Long call() throws Exception {
+            try {
+                disposer.pIShellFolder = invoke(new Callable<Long>() {
+                    public Long call() {
                         assert(isDirectory());
                         assert(parent != null);
                         long parentIShellFolder = getParentIShellFolder();
@@ -421,7 +421,10 @@
                         }
                         return pIShellFolder;
                     }
-                });
+                }, RuntimeException.class);
+            } catch (InterruptedException e) {
+                // Ignore error
+            }
         }
         return disposer.pIShellFolder;
     }
@@ -505,18 +508,23 @@
         }
 
         if (parent == rhs.parent || parent.equals(rhs.parent)) {
-            return pidlsEqual(getParentIShellFolder(), disposer.relativePIDL, rhs.disposer.relativePIDL);
+            try {
+                return pidlsEqual(getParentIShellFolder(), disposer.relativePIDL, rhs.disposer.relativePIDL);
+            } catch (InterruptedException e) {
+                return false;
+            }
         }
 
         return false;
     }
 
-    private static boolean pidlsEqual(final long pIShellFolder, final long pidl1, final long pidl2) {
-        return ShellFolder.getInvoker().invoke(new Callable<Boolean>() {
-            public Boolean call() throws Exception {
-                return (compareIDs(pIShellFolder, pidl1, pidl2) == 0);
+    private static boolean pidlsEqual(final long pIShellFolder, final long pidl1, final long pidl2)
+            throws InterruptedException {
+        return invoke(new Callable<Boolean>() {
+            public Boolean call() {
+                return compareIDs(pIShellFolder, pidl1, pidl2) == 0;
             }
-        });
+        }, RuntimeException.class);
     }
 
     // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
@@ -539,14 +547,16 @@
      * Return whether the given attribute flag is set for this object
      */
     public boolean hasAttribute(final int attribute) {
-        return ShellFolder.getInvoker().invoke(new Callable<Boolean>() {
-            public Boolean call() throws Exception {
+        Boolean result = invoke(new Callable<Boolean>() {
+            public Boolean call() {
                 // Caching at this point doesn't seem to be cost efficient
                 return (getAttributes0(getParentIShellFolder(),
                     getRelativePIDL(), attribute)
                     & attribute) != 0;
             }
         });
+
+        return result != null && result;
     }
 
     /**
@@ -561,32 +571,29 @@
     private static native int getAttributes0(long pParentIShellFolder, long pIDL, int attrsMask);
 
     // Return the path to the underlying file system object
+    // Should be called from the COM thread
     private static String getFileSystemPath(final long parentIShellFolder, final long relativePIDL) {
-        return ShellFolder.getInvoker().invoke(new Callable<String>() {
-            public String call() throws Exception {
-                int linkedFolder = ATTRIB_LINK | ATTRIB_FOLDER;
-                if (parentIShellFolder == Win32ShellFolderManager2.getNetwork().getIShellFolder() &&
-                        getAttributes0(parentIShellFolder, relativePIDL, linkedFolder) == linkedFolder) {
+        int linkedFolder = ATTRIB_LINK | ATTRIB_FOLDER;
+        if (parentIShellFolder == Win32ShellFolderManager2.getNetwork().getIShellFolder() &&
+                getAttributes0(parentIShellFolder, relativePIDL, linkedFolder) == linkedFolder) {
 
-                    String s =
-                            getFileSystemPath(Win32ShellFolderManager2.getDesktop().getIShellFolder(),
-                                    getLinkLocation(parentIShellFolder, relativePIDL, false));
-                    if (s != null && s.startsWith("\\\\")) {
-                        return s;
-                    }
-                }
-                return getDisplayNameOf(parentIShellFolder, relativePIDL, SHGDN_FORPARSING);
+            String s =
+                    getFileSystemPath(Win32ShellFolderManager2.getDesktop().getIShellFolder(),
+                            getLinkLocation(parentIShellFolder, relativePIDL, false));
+            if (s != null && s.startsWith("\\\\")) {
+                return s;
             }
-        });
+        }
+        return getDisplayNameOf(parentIShellFolder, relativePIDL, SHGDN_FORPARSING);
     }
 
     // Needs to be accessible to Win32ShellFolderManager2
-    static String getFileSystemPath(final int csidl) throws IOException {
-        return ShellFolder.getInvoker().invoke(new Callable<String>() {
-            public String call() throws Exception {
+    static String getFileSystemPath(final int csidl) throws IOException, InterruptedException {
+        return invoke(new Callable<String>() {
+            public String call() throws IOException {
                 return getFileSystemPath0(csidl);
             }
-        });
+        }, IOException.class);
     }
 
     // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
@@ -630,13 +637,14 @@
      */
     // Returns an IEnumIDList interface for an IShellFolder.  The value
     // returned must be released using releaseEnumObjects().
-    private long getEnumObjects(long pIShellFolder, final boolean includeHiddenFiles) {
-        final boolean isDesktop = (disposer.pIShellFolder == getDesktopIShellFolder());
-        return ShellFolder.getInvoker().invoke(new Callable<Long>() {
-            public Long call() throws Exception {
+    private long getEnumObjects(final boolean includeHiddenFiles) throws InterruptedException {
+        return invoke(new Callable<Long>() {
+            public Long call() {
+                boolean isDesktop = disposer.pIShellFolder == getDesktopIShellFolder();
+
                 return getEnumObjects(disposer.pIShellFolder, isDesktop, includeHiddenFiles);
             }
-        });
+        }, RuntimeException.class);
     }
 
     // Returns an IEnumIDList interface for an IShellFolder.  The value
@@ -670,58 +678,62 @@
             security.checkRead(getPath());
         }
 
-        return ShellFolder.getInvoker().invoke(new Callable<File[]>() {
-            public File[] call() throws Exception {
-                if (!isDirectory()) {
-                    return null;
-                }
-                // Links to directories are not directories and cannot be parents.
-                // This does not apply to folders in My Network Places (NetHood)
-                // because they are both links and real directories!
-                if (isLink() && !hasAttribute(ATTRIB_FOLDER)) {
-                    return new File[0];
-                }
+        try {
+            return invoke(new Callable<File[]>() {
+                public File[] call() throws InterruptedException {
+                    if (!isDirectory()) {
+                        return null;
+                    }
+                    // Links to directories are not directories and cannot be parents.
+                    // This does not apply to folders in My Network Places (NetHood)
+                    // because they are both links and real directories!
+                    if (isLink() && !hasAttribute(ATTRIB_FOLDER)) {
+                        return new File[0];
+                    }
 
-                Win32ShellFolder2 desktop = Win32ShellFolderManager2.getDesktop();
-                Win32ShellFolder2 personal = Win32ShellFolderManager2.getPersonal();
+                    Win32ShellFolder2 desktop = Win32ShellFolderManager2.getDesktop();
+                    Win32ShellFolder2 personal = Win32ShellFolderManager2.getPersonal();
 
-                // If we are a directory, we have a parent and (at least) a
-                // relative PIDL. We must first ensure we are bound to the
-                // parent so we have an IShellFolder to query.
-                long pIShellFolder = getIShellFolder();
-                // Now we can enumerate the objects in this folder.
-                ArrayList<Win32ShellFolder2> list = new ArrayList<Win32ShellFolder2>();
-                long pEnumObjects = getEnumObjects(pIShellFolder, includeHiddenFiles);
-                if (pEnumObjects != 0) {
-                    long childPIDL;
-                    int testedAttrs = ATTRIB_FILESYSTEM | ATTRIB_FILESYSANCESTOR;
-                    do {
-                        childPIDL = getNextChild(pEnumObjects);
-                        boolean releasePIDL = true;
-                        if (childPIDL != 0 &&
-                                (getAttributes0(pIShellFolder, childPIDL, testedAttrs) & testedAttrs) != 0) {
-                            Win32ShellFolder2 childFolder;
-                            if (Win32ShellFolder2.this.equals(desktop)
-                                    && personal != null
-                                    && pidlsEqual(pIShellFolder, childPIDL, personal.disposer.relativePIDL)) {
-                                childFolder = personal;
-                            } else {
-                                childFolder = new Win32ShellFolder2(Win32ShellFolder2.this, childPIDL);
-                                releasePIDL = false;
+                    // If we are a directory, we have a parent and (at least) a
+                    // relative PIDL. We must first ensure we are bound to the
+                    // parent so we have an IShellFolder to query.
+                    long pIShellFolder = getIShellFolder();
+                    // Now we can enumerate the objects in this folder.
+                    ArrayList<Win32ShellFolder2> list = new ArrayList<Win32ShellFolder2>();
+                    long pEnumObjects = getEnumObjects(includeHiddenFiles);
+                    if (pEnumObjects != 0) {
+                        long childPIDL;
+                        int testedAttrs = ATTRIB_FILESYSTEM | ATTRIB_FILESYSANCESTOR;
+                        do {
+                            childPIDL = getNextChild(pEnumObjects);
+                            boolean releasePIDL = true;
+                            if (childPIDL != 0 &&
+                                    (getAttributes0(pIShellFolder, childPIDL, testedAttrs) & testedAttrs) != 0) {
+                                Win32ShellFolder2 childFolder;
+                                if (Win32ShellFolder2.this.equals(desktop)
+                                        && personal != null
+                                        && pidlsEqual(pIShellFolder, childPIDL, personal.disposer.relativePIDL)) {
+                                    childFolder = personal;
+                                } else {
+                                    childFolder = new Win32ShellFolder2(Win32ShellFolder2.this, childPIDL);
+                                    releasePIDL = false;
+                                }
+                                list.add(childFolder);
                             }
-                            list.add(childFolder);
-                        }
-                        if (releasePIDL) {
-                            releasePIDL(childPIDL);
-                        }
-                    } while (childPIDL != 0 && !Thread.currentThread().isInterrupted());
-                    releaseEnumObjects(pEnumObjects);
+                            if (releasePIDL) {
+                                releasePIDL(childPIDL);
+                            }
+                        } while (childPIDL != 0 && !Thread.currentThread().isInterrupted());
+                        releaseEnumObjects(pEnumObjects);
+                    }
+                    return Thread.currentThread().isInterrupted()
+                        ? new File[0]
+                        : list.toArray(new ShellFolder[list.size()]);
                 }
-                return Thread.currentThread().isInterrupted()
-                    ? new File[0]
-                    : list.toArray(new ShellFolder[list.size()]);
-            }
-        });
+            }, InterruptedException.class);
+        } catch (InterruptedException e) {
+            return new File[0];
+        }
     }
 
 
@@ -730,13 +742,13 @@
      *
      * @return The child shellfolder, or null if not found.
      */
-    Win32ShellFolder2 getChildByPath(final String filePath) {
-        return ShellFolder.getInvoker().invoke(new Callable<Win32ShellFolder2>() {
-            public Win32ShellFolder2 call() throws Exception {
+    Win32ShellFolder2 getChildByPath(final String filePath) throws InterruptedException {
+        return invoke(new Callable<Win32ShellFolder2>() {
+            public Win32ShellFolder2 call() throws InterruptedException {
                 long pIShellFolder = getIShellFolder();
-                long pEnumObjects = getEnumObjects(pIShellFolder, true);
+                long pEnumObjects = getEnumObjects(true);
                 Win32ShellFolder2 child = null;
-                long childPIDL = 0;
+                long childPIDL;
 
                 while ((childPIDL = getNextChild(pEnumObjects)) != 0) {
                     if (getAttributes0(pIShellFolder, childPIDL, ATTRIB_FILESYSTEM) != 0) {
@@ -753,7 +765,7 @@
                 releaseEnumObjects(pEnumObjects);
                 return child;
             }
-        });
+        }, InterruptedException.class);
     }
 
     private Boolean cachedIsLink;
@@ -791,8 +803,8 @@
     }
 
     private ShellFolder getLinkLocation(final boolean resolve) {
-        return ShellFolder.getInvoker().invoke(new Callable<ShellFolder>() {
-            public ShellFolder call() throws Exception {
+        return invoke(new Callable<ShellFolder>() {
+            public ShellFolder call() {
                 if (!isLink()) {
                     return null;
                 }
@@ -805,6 +817,8 @@
                         location =
                                 Win32ShellFolderManager2.createShellFolderFromRelativePIDL(getDesktop(),
                                         linkLocationPIDL);
+                    } catch (InterruptedException e) {
+                        // Return null
                     } catch (InternalError e) {
                         // Could be a link to a non-bindable object, such as a network connection
                         // TODO: getIShellFolder() should throw FileNotFoundException instead
@@ -816,19 +830,12 @@
     }
 
     // Parse a display name into a PIDL relative to the current IShellFolder.
-    long parseDisplayName(final String name) throws FileNotFoundException {
-        try {
-            return ShellFolder.getInvoker().invoke(new Callable<Long>() {
-                public Long call() throws Exception {
-                    return parseDisplayName0(getIShellFolder(), name);
-                }
-            });
-        } catch (RuntimeException e) {
-            if (e.getCause() instanceof IOException) {
-                throw new FileNotFoundException("Could not find file " + name);
+    long parseDisplayName(final String name) throws IOException, InterruptedException {
+        return invoke(new Callable<Long>() {
+            public Long call() throws IOException {
+                return parseDisplayName0(getIShellFolder(), name);
             }
-            throw e;
-        }
+        }, IOException.class);
     }
 
     // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
@@ -846,8 +853,8 @@
     public String getDisplayName() {
         if (displayName == null) {
             displayName =
-                ShellFolder.getInvoker().invoke(new Callable<String>() {
-                    public String call() throws Exception {
+                invoke(new Callable<String>() {
+                    public String call() {
                         return getDisplayNameOf(getParentIShellFolder(),
                                 getRelativePIDL(), SHGDN_NORMAL);
                     }
@@ -867,8 +874,8 @@
         if (folderType == null) {
             final long absolutePIDL = getAbsolutePIDL();
             folderType =
-                ShellFolder.getInvoker().invoke(new Callable<String>() {
-                    public String call() throws Exception {
+                invoke(new Callable<String>() {
+                    public String call() {
                         return getFolderType(absolutePIDL);
                     }
                 });
@@ -926,15 +933,12 @@
 
     public static native int[] getFileChooserBitmapBits();
 
+    // Should be called from the COM thread
     private long getIShellIcon() {
         if (pIShellIcon == -1L) {
-            pIShellIcon =
-                ShellFolder.getInvoker().invoke(new Callable<Long>() {
-                    public Long call() throws Exception {
-                        return getIShellIcon(getIShellFolder());
-                    }
-                });
+            pIShellIcon = getIShellIcon(getIShellFolder());
         }
+
         return pIShellIcon;
     }
 
@@ -988,8 +992,8 @@
         Image icon = getLargeIcon ? largeIcon : smallIcon;
         if (icon == null) {
             icon =
-                ShellFolder.getInvoker().invoke(new Callable<Image>() {
-                    public Image call() throws Exception {
+                invoke(new Callable<Image>() {
+                    public Image call() {
                         Image newIcon = null;
                         if (isFileSystem()) {
                             long parentIShellIcon = (parent != null)
@@ -1113,8 +1117,8 @@
     private static final int LVCFMT_CENTER = 2;
 
     public ShellFolderColumnInfo[] getFolderColumns() {
-        return ShellFolder.getInvoker().invoke(new Callable<ShellFolderColumnInfo[]>() {
-            public ShellFolderColumnInfo[] call() throws Exception {
+        return invoke(new Callable<ShellFolderColumnInfo[]>() {
+            public ShellFolderColumnInfo[] call() {
                 ShellFolderColumnInfo[] columns = doGetColumnInfo(getIShellFolder());
 
                 if (columns != null) {
@@ -1143,8 +1147,8 @@
     }
 
     public Object getFolderColumnValue(final int column) {
-        return ShellFolder.getInvoker().invoke(new Callable<Object>() {
-            public Object call() throws Exception {
+        return invoke(new Callable<Object>() {
+            public Object call() {
                 return doGetColumnValue(getParentIShellFolder(), getRelativePIDL(), column);
             }
         });
@@ -1163,8 +1167,8 @@
     public void sortChildren(final List<? extends File> files) {
         // To avoid loads of synchronizations with Invoker and improve performance we
         // synchronize the whole code of the sort method once
-        getInvoker().invoke(new Callable<Void>() {
-            public Void call() throws Exception {
+        invoke(new Callable<Void>() {
+            public Void call() {
                 Collections.sort(files, new ColumnComparator(getIShellFolder(), 0));
 
                 return null;
@@ -1184,19 +1188,21 @@
 
         // compares 2 objects within this folder by the specified column
         public int compare(final File o, final File o1) {
-            return ShellFolder.getInvoker().invoke(new Callable<Integer>() {
-                public Integer call() throws Exception {
+            Integer result = invoke(new Callable<Integer>() {
+                public Integer call() {
                     if (o instanceof Win32ShellFolder2
-                            && o1 instanceof Win32ShellFolder2) {
+                        && o1 instanceof Win32ShellFolder2) {
                         // delegates comparison to native method
                         return compareIDsByColumn(parentIShellFolder,
-                                ((Win32ShellFolder2) o).getRelativePIDL(),
-                                ((Win32ShellFolder2) o1).getRelativePIDL(),
-                                columnIdx);
+                            ((Win32ShellFolder2) o).getRelativePIDL(),
+                            ((Win32ShellFolder2) o1).getRelativePIDL(),
+                            columnIdx);
                     }
                     return 0;
                 }
             });
+
+            return result == null ? 0 : result;
         }
     }
 }
--- a/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java	Wed Jul 29 00:12:45 2009 -0700
+++ b/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java	Wed Jul 29 00:14:56 2009 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2003-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
@@ -58,10 +58,15 @@
     }
 
     public ShellFolder createShellFolder(File file) throws FileNotFoundException {
-        return createShellFolder(getDesktop(), file);
+        try {
+            return createShellFolder(getDesktop(), file);
+        } catch (InterruptedException e) {
+            throw new FileNotFoundException("Execution was interrupted");
+        }
     }
 
-    static Win32ShellFolder2 createShellFolder(Win32ShellFolder2 parent, File file) throws FileNotFoundException {
+    static Win32ShellFolder2 createShellFolder(Win32ShellFolder2 parent, File file)
+            throws FileNotFoundException, InterruptedException {
         long pIDL;
         try {
             pIDL = parent.parseDisplayName(file.getCanonicalPath());
@@ -77,7 +82,8 @@
         return folder;
     }
 
-    static Win32ShellFolder2 createShellFolderFromRelativePIDL(Win32ShellFolder2 parent, long pIDL) {
+    static Win32ShellFolder2 createShellFolderFromRelativePIDL(Win32ShellFolder2 parent, long pIDL)
+            throws InterruptedException {
         // Walk down this relative pIDL, creating new nodes for each of the entries
         while (pIDL != 0) {
             long curPIDL = Win32ShellFolder2.copyFirstPIDLEntry(pIDL);
@@ -108,7 +114,9 @@
             try {
                 desktop = new Win32ShellFolder2(DESKTOP);
             } catch (IOException e) {
-                desktop = null;
+                // Ignore error
+            } catch (InterruptedException e) {
+                // Ignore error
             }
         }
         return desktop;
@@ -119,7 +127,9 @@
             try {
                 drives = new Win32ShellFolder2(DRIVES);
             } catch (IOException e) {
-                drives = null;
+                // Ignore error
+            } catch (InterruptedException e) {
+                // Ignore error
             }
         }
         return drives;
@@ -132,8 +142,10 @@
                 if (path != null) {
                     recent = createShellFolder(getDesktop(), new File(path));
                 }
+            } catch (InterruptedException e) {
+                // Ignore error
             } catch (IOException e) {
-                recent = null;
+                // Ignore error
             }
         }
         return recent;
@@ -144,7 +156,9 @@
             try {
                 network = new Win32ShellFolder2(NETWORK);
             } catch (IOException e) {
-                network = null;
+                // Ignore error
+            } catch (InterruptedException e) {
+                // Ignore error
             }
         }
         return network;
@@ -164,8 +178,10 @@
                         personal.setIsPersonal();
                     }
                 }
+            } catch (InterruptedException e) {
+                // Ignore error
             } catch (IOException e) {
-                personal = null;
+                // Ignore error
             }
         }
         return personal;
@@ -267,6 +283,9 @@
                     }
                 } catch (IOException e) {
                     // Skip this value
+                } catch (InterruptedException e) {
+                    // Return empty result
+                    return new File[0];
                 }
             } while (value != null);
 
@@ -476,33 +495,39 @@
             return comThread;
         }
 
-        public <T> T invoke(Callable<T> task) {
-            try {
-                if (Thread.currentThread() == comThread) {
-                    // if it's already called from the COM
-                    // thread, we don't need to delegate the task
-                    return task.call();
-                } else {
-                    while (true) {
-                        Future<T> future = submit(task);
+        public <T> T invoke(Callable<T> task) throws Exception {
+            if (Thread.currentThread() == comThread) {
+                // if it's already called from the COM
+                // thread, we don't need to delegate the task
+                return task.call();
+            } else {
+                Future<T> future;
+
+                try {
+                    future = submit(task);
+                } catch (RejectedExecutionException e) {
+                    throw new InterruptedException(e.getMessage());
+                }
 
-                        try {
-                            return future.get();
-                        } catch (InterruptedException e) {
-                            // Repeat the attempt
-                            future.cancel(true);
-                        }
+                try {
+                    return future.get();
+                } catch (InterruptedException e) {
+                    future.cancel(true);
+
+                    throw e;
+                } catch (ExecutionException e) {
+                    Throwable cause = e.getCause();
+
+                    if (cause instanceof Exception) {
+                        throw (Exception) cause;
                     }
+
+                    if (cause instanceof Error) {
+                        throw (Error) cause;
+                    }
+
+                    throw new RuntimeException("Unexpected error", cause);
                 }
-            } catch (Exception e) {
-                Throwable cause = (e instanceof ExecutionException) ? e.getCause() : e;
-                if (cause instanceof RuntimeException) {
-                    throw (RuntimeException) cause;
-                }
-                if (cause instanceof Error) {
-                    throw (Error) cause;
-                }
-                throw new RuntimeException(cause);
             }
         }
     }
--- a/jdk/src/windows/native/sun/windows/awt_Component.cpp	Wed Jul 29 00:12:45 2009 -0700
+++ b/jdk/src/windows/native/sun/windows/awt_Component.cpp	Wed Jul 29 00:14:56 2009 -0700
@@ -3739,11 +3739,12 @@
 
 MsgRouting AwtComponent::WmImeSetContext(BOOL fSet, LPARAM *lplParam)
 {
-    // This message causes native status window shown even it is disabled.  So don't
-    // let DefWindowProc process this message if this IMC is disabled.
+    // If the Windows input context is disabled, do not let Windows
+    // display any UIs.
     HIMC hIMC = ImmGetContext();
     if (hIMC == NULL) {
-        return mrConsume;
+        *lplParam = 0;
+        return mrDoDefault;
     }
 
     if (fSet) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JInternalFrame/Test6505027.java	Wed Jul 29 00:14:56 2009 -0700
@@ -0,0 +1,136 @@
+/*
+ * 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 6505027
+ * @summary Tests focus problem inside internal frame
+ * @author Sergey Malenkov
+ */
+
+import java.awt.AWTException;
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.KeyboardFocusManager;
+import java.awt.Point;
+import java.awt.Robot;
+import java.awt.event.InputEvent;
+import javax.swing.DefaultCellEditor;
+import javax.swing.JComboBox;
+import javax.swing.JDesktopPane;
+import javax.swing.JFrame;
+import javax.swing.JInternalFrame;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.JTextField;
+import javax.swing.SwingUtilities;
+import javax.swing.WindowConstants;
+import javax.swing.table.DefaultTableModel;
+import javax.swing.table.TableColumn;
+
+public class Test6505027 implements Runnable {
+
+    private static final boolean INTERNAL = true;
+    private static final boolean TERMINATE = true;
+
+    private static final int WIDTH = 450;
+    private static final int HEIGHT = 200;
+    private static final int OFFSET = 10;
+    private static final long PAUSE = 2048L;
+
+    private static final String[] COLUMNS = { "Size", "Shape" }; // NON-NLS
+    private static final String[] ITEMS = { "a", "b", "c", "d" }; // NON-NLS
+    private static final String KEY = "terminateEditOnFocusLost"; // NON-NLS
+
+    public static void main(String[] args) {
+        SwingUtilities.invokeLater(new Test6505027());
+
+        Component component = null;
+        while (component == null) {
+            try {
+                Thread.sleep(PAUSE);
+            }
+            catch (InterruptedException exception) {
+                // ignore interrupted exception
+            }
+            component = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
+        }
+        if (!component.getClass().equals(JComboBox.class)) {
+            throw new Error("unexpected focus owner: " + component);
+        }
+        SwingUtilities.getWindowAncestor(component).dispose();
+    }
+
+    private JTable table;
+    private Point point;
+
+    public void run() {
+        if (this.table == null) {
+            JFrame main = new JFrame();
+            main.setSize(WIDTH + OFFSET * 3, HEIGHT + OFFSET * 5);
+            main.setLocationRelativeTo(null);
+            main.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
+            main.setVisible(true);
+
+            Container container = main;
+            if (INTERNAL) {
+                JInternalFrame frame = new JInternalFrame();
+                frame.setBounds(OFFSET, OFFSET, WIDTH, HEIGHT);
+                frame.setVisible(true);
+
+                JDesktopPane desktop = new JDesktopPane();
+                desktop.add(frame, new Integer(1));
+
+                container.add(desktop);
+                container = frame;
+            }
+            this.table = new JTable(new DefaultTableModel(COLUMNS, 2));
+            if (TERMINATE) {
+                this.table.putClientProperty(KEY, Boolean.TRUE);
+            }
+            TableColumn column = this.table.getColumn(COLUMNS[1]);
+            column.setCellEditor(new DefaultCellEditor(new JComboBox(ITEMS)));
+
+            container.add(BorderLayout.NORTH, new JTextField());
+            container.add(BorderLayout.CENTER, new JScrollPane(this.table));
+
+            SwingUtilities.invokeLater(this);
+        }
+        else if (this.point == null) {
+            this.point = this.table.getCellRect(1, 1, false).getLocation();
+            SwingUtilities.convertPointToScreen(this.point, this.table);
+            SwingUtilities.invokeLater(this);
+        }
+        else {
+            try {
+                Robot robot = new Robot();
+                robot.mouseMove(this.point.x + 1, this.point.y + 1);
+                robot.mousePress(InputEvent.BUTTON1_MASK);
+            }
+            catch (AWTException exception) {
+                throw new Error("unexpected exception", exception);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JInternalFrame/Test6802868.java	Wed Jul 29 00:14:56 2009 -0700
@@ -0,0 +1,108 @@
+/*
+ * 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 6802868
+ * @summary JInternalFrame is not maximized when maximized parent frame
+ * @author Alexander Potochkin
+ */
+
+import sun.awt.SunToolkit;
+
+import java.awt.Dimension;
+import java.awt.Point;
+import java.awt.Robot;
+import java.awt.Toolkit;
+import java.beans.PropertyVetoException;
+import javax.swing.JDesktopPane;
+import javax.swing.JFrame;
+import javax.swing.JInternalFrame;
+import javax.swing.SwingUtilities;
+
+public class Test6802868 {
+    static JInternalFrame jif;
+    static JFrame frame;
+    static Dimension size;
+    static Point location;
+
+    public static void main(String[] args) throws Exception {
+        Robot robot = new Robot();
+        robot.setAutoDelay(20);
+        SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
+
+        SwingUtilities.invokeAndWait(new Runnable() {
+            public void run() {
+                frame = new JFrame();
+                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+
+                JDesktopPane jdp = new JDesktopPane();
+                frame.getContentPane().add(jdp);
+
+                jif = new JInternalFrame("Title", true, true, true, true);
+                jdp.add(jif);
+                jif.setVisible(true);
+
+                frame.setSize(200, 200);
+                frame.setLocationRelativeTo(null);
+                frame.setVisible(true);
+
+                try {
+                    jif.setMaximum(true);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        });
+        toolkit.realSync();
+        SwingUtilities.invokeAndWait(new Runnable() {
+            public void run() {
+                size = jif.getSize();
+                frame.setSize(300, 300);
+            }
+        });
+        toolkit.realSync();
+        SwingUtilities.invokeAndWait(new Runnable() {
+            public void run() {
+                if (jif.getSize().equals(size)) {
+                    throw new RuntimeException("InternalFrame hasn't changed its size");
+                }
+                try {
+                    jif.setIcon(true);
+                } catch (PropertyVetoException e) {
+                    e.printStackTrace();
+                }
+                location = jif.getDesktopIcon().getLocation();
+                frame.setSize(400, 400);
+            }
+        });
+        toolkit.realSync();
+        SwingUtilities.invokeAndWait(new Runnable() {
+            public void run() {
+                if (jif.getDesktopIcon().getLocation().equals(location)) {
+                    throw new RuntimeException("JDesktopIcon hasn't moved");
+                }
+            }
+        });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JScrollPane/Test6526631.java	Wed Jul 29 00:14:56 2009 -0700
@@ -0,0 +1,102 @@
+/*
+ * 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 6526631
+ * @summary Resizes right-oriented scroll pane
+ * @author Sergey Malenkov
+ * @library ..
+ * @build SwingTest
+ * @run main Test6526631
+ */
+
+import java.awt.Dimension;
+import javax.swing.JFrame;
+import javax.swing.JScrollBar;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+import javax.swing.JViewport;
+
+import static java.awt.ComponentOrientation.RIGHT_TO_LEFT;
+
+public class Test6526631 {
+
+    private static final int COLS = 90;
+    private static final int ROWS = 50;
+    private static final int OFFSET = 10;
+
+    public static void main(String[] args) {
+        SwingTest.start(Test6526631.class);
+    }
+
+    private final JScrollPane pane;
+    private final JFrame frame;
+
+    public Test6526631(JFrame frame) {
+        this.pane = new JScrollPane(new JTextArea(ROWS, COLS));
+        this.pane.setComponentOrientation(RIGHT_TO_LEFT);
+        this.frame = frame;
+        this.frame.add(this.pane);
+    }
+
+    private void update(int offset) {
+        Dimension size = this.frame.getSize();
+        size.width += offset;
+        this.frame.setSize(size);
+    }
+
+    public void validateFirst() {
+        validateThird();
+        update(OFFSET);
+    }
+
+    public void validateSecond() {
+        validateThird();
+        update(-OFFSET);
+    }
+
+    public void validateThird() {
+        JViewport viewport = this.pane.getViewport();
+        JScrollBar scroller = this.pane.getHorizontalScrollBar();
+        if (!scroller.getComponentOrientation().equals(RIGHT_TO_LEFT)) {
+            throw new IllegalStateException("unexpected component orientation");
+        }
+        int value = scroller.getValue();
+        if (value != 0) {
+            throw new IllegalStateException("unexpected scroll value");
+        }
+        int extent = viewport.getExtentSize().width;
+        if (extent != scroller.getVisibleAmount()) {
+            throw new IllegalStateException("unexpected visible amount");
+        }
+        int size = viewport.getViewSize().width;
+        if (size != scroller.getMaximum()) {
+            throw new IllegalStateException("unexpected maximum");
+        }
+        int pos = size - extent - value;
+        if (pos != viewport.getViewPosition().x) {
+            throw new IllegalStateException("unexpected position");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/SwingTest.java	Wed Jul 29 00:14:56 2009 -0700
@@ -0,0 +1,160 @@
+/*
+ * 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.
+ */
+
+import java.io.PrintWriter;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.TreeSet;
+import javax.swing.JFrame;
+
+import static javax.swing.SwingUtilities.invokeLater;
+
+/**
+ * SwingTestHelper is a utility class for writing regression tests
+ * that require interacting with the UI.
+ *
+ * @author Sergey A. Malenkov
+ */
+final class SwingTest implements Runnable {
+
+    private static final int WIDTH = 640;
+    private static final int HEIGHT = 480;
+
+    public static void start(Class<?> type) {
+        new SwingTest(type).start();
+    }
+
+    private final PrintWriter writer = new PrintWriter(System.out, true);
+
+    private Class<?> type;
+    private JFrame frame;
+    private Iterator<Method> methods;
+    private Object object;
+    private Method method;
+    private Throwable error;
+
+    private SwingTest(Class<?> type) {
+        this.type = type;
+    }
+
+    public void run() {
+        synchronized (this.writer) {
+            if (this.error != null) {
+                this.frame.dispose();
+                this.frame = null;
+            }
+            else if (this.object == null) {
+                invoke();
+                Set<Method> methods = new TreeSet<Method>(new Comparator<Method>() {
+                    public int compare(Method first, Method second) {
+                        return first.getName().compareTo(second.getName());
+                    }
+                });
+                for (Method method : this.type.getMethods()) {
+                    if (method.getDeclaringClass().equals(this.type)) {
+                        if (method.getReturnType().equals(void.class)) {
+                            if (0 == method.getParameterTypes().length) {
+                                methods.add(method);
+                            }
+                        }
+                    }
+                }
+                this.methods = methods.iterator();
+            }
+            else if (this.method != null) {
+                invoke();
+            }
+            else if (this.methods.hasNext()) {
+                this.method = this.methods.next();
+            }
+            else {
+                this.frame.dispose();
+                this.frame = null;
+                this.type = null;
+            }
+            this.writer.notifyAll();
+        }
+    }
+
+    private void start() {
+        synchronized (this.writer) {
+            while (this.type != null) {
+                if ((this.method != null) && Modifier.isStatic(this.method.getModifiers())) {
+                    invoke();
+                }
+                else {
+                    invokeLater(this);
+                    try {
+                        this.writer.wait();
+                    }
+                    catch (InterruptedException exception) {
+                        exception.printStackTrace(this.writer);
+                    }
+                }
+                if ((this.frame == null) && (this.error != null)) {
+                    throw new Error("unexpected error", this.error);
+                }
+            }
+        }
+    }
+
+    private void invoke() {
+        try {
+            if (this.method != null) {
+                this.writer.println(this.method);
+                this.method.invoke(this.object);
+                this.method = null;
+            }
+            else {
+                this.writer.println(this.type);
+                this.frame = new JFrame(this.type.getSimpleName());
+                this.frame.setSize(WIDTH, HEIGHT);
+                this.frame.setLocationRelativeTo(null);
+                this.object = this.type.getConstructor(JFrame.class).newInstance(this.frame);
+                this.frame.setVisible(true);
+            }
+        }
+        catch (NoSuchMethodException exception) {
+            this.error = exception;
+        }
+        catch (SecurityException exception) {
+            this.error = exception;
+        }
+        catch (IllegalAccessException exception) {
+            this.error = exception;
+        }
+        catch (IllegalArgumentException exception) {
+            this.error = exception;
+        }
+        catch (InstantiationException exception) {
+            this.error = exception;
+        }
+        catch (InvocationTargetException exception) {
+            this.error = exception.getTargetException();
+        }
+    }
+}