changeset 192:a15dae99414c

Merge
author mlapshin
date Thu, 24 Apr 2008 05:58:57 -0700
parents fb57027902e0 40414219305f
children a883bd215e94
files
diffstat 11 files changed, 386 insertions(+), 168 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/javax/swing/JEditorPane.java	Fri Apr 18 16:40:32 2008 -0700
+++ b/src/share/classes/javax/swing/JEditorPane.java	Thu Apr 24 05:58:57 2008 -0700
@@ -429,9 +429,8 @@
             // different url or POST method, load the new content
 
             int p = getAsynchronousLoadPriority(getDocument());
-            if ((postData == null) || (p < 0)) {
-                // Either we do not have POST data, or should submit the data
-                // synchronously.
+            if (p < 0) {
+                // open stream synchronously
                 InputStream in = getStream(page);
                 if (kit != null) {
                     Document doc = initializeModel(kit, page);
@@ -440,22 +439,13 @@
                     // view notifications slowing it down (i.e. best synchronous
                     // behavior) or set the model and start to feed it on a separate
                     // thread (best asynchronous behavior).
-                    synchronized(this) {
-                        if (loading != null) {
-                            // we are loading asynchronously, so we need to cancel
-                            // the old stream.
-                            loading.cancel();
-                            loading = null;
-                        }
-                    }
                     p = getAsynchronousLoadPriority(doc);
                     if (p >= 0) {
                         // load asynchronously
                         setDocument(doc);
                         synchronized(this) {
-                            loading = new PageStream(in);
-                            Thread pl = new PageLoader(doc, loading, p, loaded, page);
-                            pl.start();
+                            pageLoader = new PageLoader(doc, in, loaded, page);
+                            pageLoader.execute();
                         }
                         return;
                     }
@@ -464,11 +454,15 @@
                     reloaded = true;
                 }
             } else {
-                // We have POST data and should send it asynchronously.
-                // Send (and subsequentally read) data in separate thread.
+                // we may need to cancel background loading
+                if (pageLoader != null) {
+                    pageLoader.cancel(true);
+                }
+
+                // Do everything in a background thread.
                 // Model initialization is deferred to that thread, too.
-                Thread pl = new PageLoader(null, null, p, loaded, page);
-                pl.start();
+                pageLoader = new PageLoader(null, null, loaded, page);
+                pageLoader.execute();
                 return;
             }
         }
@@ -604,44 +598,38 @@
 
 
     /**
-     * Thread to load a stream into the text document model.
+     * Loads a stream into the text document model.
      */
-    class PageLoader extends Thread {
+    class PageLoader extends SwingWorker<URL, Object> {
 
         /**
          * Construct an asynchronous page loader.
          */
-        PageLoader(Document doc, InputStream in, int priority, URL old,
-                   URL page) {
-            setPriority(priority);
+        PageLoader(Document doc, InputStream in, URL old, URL page) {
             this.in = in;
             this.old = old;
             this.page = page;
             this.doc = doc;
         }
 
-        boolean pageLoaded = false;
-
         /**
          * Try to load the document, then scroll the view
          * to the reference (if specified).  When done, fire
          * a page property change event.
          */
-        public void run() {
+        protected URL doInBackground() {
+            boolean pageLoaded = false;
             try {
                 if (in == null) {
                     in = getStream(page);
                     if (kit == null) {
                         // We received document of unknown content type.
-                        UIManager.getLookAndFeel().provideErrorFeedback(
-                                JEditorPane.this);
-                        return;
-                    }
-                    // Access to <code>loading</code> should be synchronized.
-                    synchronized(JEditorPane.this) {
-                        in = loading = new PageStream(in);
+                        UIManager.getLookAndFeel().
+                                provideErrorFeedback(JEditorPane.this);
+                        return old;
                     }
                 }
+
                 if (doc == null) {
                     try {
                         SwingUtilities.invokeAndWait(new Runnable() {
@@ -653,11 +641,11 @@
                     } catch (InvocationTargetException ex) {
                         UIManager.getLookAndFeel().provideErrorFeedback(
                                                             JEditorPane.this);
-                        return;
+                        return old;
                     } catch (InterruptedException ex) {
                         UIManager.getLookAndFeel().provideErrorFeedback(
                                                             JEditorPane.this);
-                        return;
+                        return old;
                     }
                 }
 
@@ -682,16 +670,14 @@
             } catch (IOException ioe) {
                 UIManager.getLookAndFeel().provideErrorFeedback(JEditorPane.this);
             } finally {
-                synchronized(JEditorPane.this) {
-                    loading = null;
+                if (pageLoaded) {
+                    SwingUtilities.invokeLater(new Runnable() {
+                        public void run() {
+                            JEditorPane.this.firePropertyChange("page", old, page);
+                        }
+                    });
                 }
-                SwingUtilities.invokeLater(new Runnable() {
-                    public void run() {
-                        if (pageLoaded) {
-                            firePropertyChange("page", old, page);
-                        }
-                    }
-                });
+                return (pageLoaded ? page : old);
             }
         }
 
@@ -718,51 +704,6 @@
         Document doc;
     }
 
-    static class PageStream extends FilterInputStream {
-
-        boolean canceled;
-
-        public PageStream(InputStream i) {
-            super(i);
-            canceled = false;
-        }
-
-        /**
-         * Cancel the loading of the stream by throwing
-         * an IOException on the next request.
-         */
-        public synchronized void cancel() {
-            canceled = true;
-        }
-
-        protected synchronized void checkCanceled() throws IOException {
-            if (canceled) {
-                throw new IOException("page canceled");
-            }
-        }
-
-        public int read() throws IOException {
-            checkCanceled();
-            return super.read();
-        }
-
-        public long skip(long n) throws IOException {
-            checkCanceled();
-            return super.skip(n);
-        }
-
-        public int available() throws IOException {
-            checkCanceled();
-            return super.available();
-        }
-
-        public void reset() throws IOException {
-            checkCanceled();
-            super.reset();
-        }
-
-    }
-
     /**
      * Fetches a stream for the given URL, which is about to
      * be loaded by the <code>setPage</code> method.  By
@@ -1179,11 +1120,6 @@
      * current selection.  The replacement text will have the
      * attributes currently defined for input.  If the component is not
      * editable, beep and return.
-     * <p>
-     * This method is thread safe, although most Swing methods
-     * are not. Please see
-     * <A HREF="http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html">How
-     * to Use Threads</A> for more information.
      *
      * @param content  the content to replace the selection with.  This
      *   value can be <code>null</code>
@@ -1454,11 +1390,6 @@
      * create a StringReader and call the read method.  In this case the model
      * would be replaced after it was initialized with the contents of the
      * string.
-     * <p>
-     * This method is thread safe, although most Swing methods
-     * are not. Please see
-     * <A HREF="http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html">How
-     * to Use Threads</A> for more information.
      *
      * @param t the new text to be set; if <code>null</code> the old
      *    text will be deleted
@@ -1573,11 +1504,7 @@
 
     // --- variables ---------------------------------------
 
-    /**
-     * Stream currently loading asynchronously (potentially cancelable).
-     * Access to this variable should be synchronized.
-     */
-    PageStream loading;
+    private SwingWorker<URL, Object> pageLoader;
 
     /**
      * Current content binding of the editor.
--- a/src/share/classes/javax/swing/JTextArea.java	Fri Apr 18 16:40:32 2008 -0700
+++ b/src/share/classes/javax/swing/JTextArea.java	Thu Apr 24 05:58:57 2008 -0700
@@ -444,11 +444,6 @@
     /**
      * Inserts the specified text at the specified position.  Does nothing
      * if the model is null or if the text is null or empty.
-     * <p>
-     * This method is thread safe, although most Swing methods
-     * are not. Please see
-     * <A HREF="http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html">How
-     * to Use Threads</A> for more information.
      *
      * @param str the text to insert
      * @param pos the position at which to insert >= 0
@@ -471,11 +466,6 @@
     /**
      * Appends the given text to the end of the document.  Does nothing if
      * the model is null or the string is null or empty.
-     * <p>
-     * This method is thread safe, although most Swing methods
-     * are not. Please see
-     * <A HREF="http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html">How
-     * to Use Threads</A> for more information.
      *
      * @param str the text to insert
      * @see #insert
@@ -494,11 +484,6 @@
      * Replaces text from the indicated start to end position with the
      * new text specified.  Does nothing if the model is null.  Simply
      * does a delete if the new string is null or empty.
-     * <p>
-     * This method is thread safe, although most Swing methods
-     * are not. Please see
-     * <A HREF="http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html">How
-     * to Use Threads</A> for more information.
      *
      * @param str the text to use as the replacement
      * @param start the start position >= 0
--- a/src/share/classes/javax/swing/JTextPane.java	Fri Apr 18 16:40:32 2008 -0700
+++ b/src/share/classes/javax/swing/JTextPane.java	Thu Apr 24 05:58:57 2008 -0700
@@ -167,11 +167,6 @@
      * current selection.  The replacement text will have the
      * attributes currently defined for input at the point of
      * insertion.  If the document is not editable, beep and return.
-     * <p>
-     * This method is thread safe, although most Swing methods
-     * are not. Please see
-     * <A HREF="http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html">How
-     * to Use Threads</A> for more information.
      *
      * @param content  the content to replace the selection with
      */
@@ -229,11 +224,6 @@
      * a value of <code>0.75</code> will cause 75 percent of the
      * component to be above the baseline, and 25 percent of the
      * component to be below the baseline.
-     * <p>
-     * This method is thread safe, although most Swing methods
-     * are not. Please see
-     * <A HREF="http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html">How
-     * to Use Threads</A> for more information.
      *
      * @param c    the component to insert
      */
@@ -252,11 +242,6 @@
      * current position of the caret.  This is represented in
      * the associated document as an attribute of one character
      * of content.
-     * <p>
-     * This method is thread safe, although most Swing methods
-     * are not. Please see
-     * <A HREF="http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html">How
-     * to Use Threads</A> for more information.
      *
      * @param g    the icon to insert
      * @see Icon
@@ -320,11 +305,6 @@
      * through the logical style assigned to the paragraph, which
      * in term may resolve through some hierarchy completely
      * independent of the element hierarchy in the document.
-     * <p>
-     * This method is thread safe, although most Swing methods
-     * are not. Please see
-     * <A HREF="http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html">How
-     * to Use Threads</A> for more information.
      *
      * @param s  the logical style to assign to the paragraph,
      *          or <code>null</code> for no style
@@ -367,11 +347,6 @@
      * is no selection, the attributes are applied to
      * the input attribute set which defines the attributes
      * for any new text that gets inserted.
-     * <p>
-     * This method is thread safe, although most Swing methods
-     * are not. Please see
-     * <A HREF="http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html">How
-     * to Use Threads</A> for more information.
      *
      * @param attr the attributes
      * @param replace if true, then replace the existing attributes first
@@ -412,11 +387,6 @@
      * to the paragraphs that intersect the selection.
      * If there is no selection, the attributes are applied
      * to the paragraph at the current caret position.
-     * <p>
-     * This method is thread safe, although most Swing methods
-     * are not. Please see
-     * <A HREF="http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html">How
-     * to Use Threads</A> for more information.
      *
      * @param attr the non-<code>null</code> attributes
      * @param replace if true, replace the existing attributes first
--- a/src/share/classes/javax/swing/Popup.java	Fri Apr 18 16:40:32 2008 -0700
+++ b/src/share/classes/javax/swing/Popup.java	Thu Apr 24 05:58:57 2008 -0700
@@ -229,7 +229,15 @@
             // Popups are typically transient and most likely won't benefit
             // from true double buffering.  Turn it off here.
             getRootPane().setUseTrueDoubleBuffering(false);
-            setAlwaysOnTop(true);
+            // Try to set "always-on-top" for the popup window.
+            // Applets usually don't have sufficient permissions to do it.
+            // In this case simply ignore the exception.
+            try {
+                setAlwaysOnTop(true);
+            } catch (SecurityException se) {
+                // setAlwaysOnTop is restricted,
+                // the exception is ignored
+            }
         }
 
         public void update(Graphics g) {
--- a/src/share/classes/javax/swing/ScrollPaneLayout.java	Fri Apr 18 16:40:32 2008 -0700
+++ b/src/share/classes/javax/swing/ScrollPaneLayout.java	Thu Apr 24 05:58:57 2008 -0700
@@ -488,10 +488,14 @@
         Dimension viewSize = null;
         Component view = null;
 
-        if (viewport !=  null) {
+        if (viewport != null) {
             extentSize = viewport.getPreferredSize();
             view = viewport.getView();
-            viewSize  = view.getPreferredSize();
+            if (view != null) {
+                viewSize = view.getPreferredSize();
+            } else {
+                viewSize = new Dimension(0, 0);
+            }
         }
 
         /* If there's a viewport add its preferredSize.
--- a/src/share/classes/javax/swing/text/JTextComponent.java	Fri Apr 18 16:40:32 2008 -0700
+++ b/src/share/classes/javax/swing/text/JTextComponent.java	Thu Apr 24 05:58:57 2008 -0700
@@ -1349,11 +1349,6 @@
      * This is the method that is used by the default implementation
      * of the action for inserting content that gets bound to the
      * keymap actions.
-     * <p>
-     * This method is thread safe, although most Swing methods
-     * are not. Please see
-     * <A HREF="http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html">How
-     * to Use Threads</A> for more information.
      *
      * @param content  the content to replace the selection with
      */
@@ -1687,12 +1682,8 @@
      * or empty, has the effect of simply deleting the old text.
      * When text has been inserted, the resulting caret location
      * is determined by the implementation of the caret class.
+     *
      * <p>
-     * This method is thread safe, although most Swing methods
-     * are not. Please see
-     * <A HREF="http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html">How
-     * to Use Threads</A> for more information.
-     *
      * Note that text is not a bound property, so no <code>PropertyChangeEvent
      * </code> is fired when it changes. To listen for changes to the text,
      * use <code>DocumentListener</code>.
--- a/src/solaris/native/sun/awt/gtk2_interface.c	Fri Apr 18 16:40:32 2008 -0700
+++ b/src/solaris/native/sun/awt/gtk2_interface.c	Thu Apr 24 05:58:57 2008 -0700
@@ -333,6 +333,7 @@
 static GdkPixbuf* (*fp_gtk_widget_render_icon)(GtkWidget *widget,
         const gchar *stock_id, GtkIconSize size, const gchar *detail);
 static void (*fp_gtk_widget_set_name)(GtkWidget *widget, const gchar *name);
+static void (*fp_gtk_widget_set_parent)(GtkWidget *widget, GtkWidget *parent);
 static void (*fp_gtk_widget_set_direction)(GtkWidget *widget,
         GtkTextDirection direction);
 static void (*fp_gtk_widget_style_get)(GtkWidget *widget,
@@ -570,6 +571,8 @@
             dl_symbol("gtk_widget_render_icon");
         fp_gtk_widget_set_name =
             dl_symbol("gtk_widget_set_name");
+        fp_gtk_widget_set_parent =
+            dl_symbol("gtk_widget_set_parent");
         fp_gtk_widget_set_direction =
             dl_symbol("gtk_widget_set_direction");
         fp_gtk_widget_style_get =
@@ -1040,7 +1043,7 @@
                     (NULL == gtk2_widgets[_GTK_COMBO_BOX_ARROW_BUTTON_TYPE]))
             {
                 gtk2_widgets[_GTK_COMBO_BOX_ARROW_BUTTON_TYPE] =
-                     (*fp_gtk_button_new)();
+                     (*fp_gtk_toggle_button_new)();
             }
             result = gtk2_widgets[_GTK_COMBO_BOX_ARROW_BUTTON_TYPE];
             break;
@@ -1414,12 +1417,20 @@
                  widget_type == COMBO_BOX_TEXT_FIELD)
         {
             /*
-             * We add a regular GtkButton/GtkEntry to a GtkComboBoxEntry
-             * in order to trick engines into thinking it's a real combobox
-             * arrow button/text field.
-             */
+            * We add a regular GtkButton/GtkEntry to a GtkComboBoxEntry
+            * in order to trick engines into thinking it's a real combobox
+            * arrow button/text field.
+            */
             GtkWidget *combo = (*fp_gtk_combo_box_entry_new)();
-            (*fp_gtk_container_add)((GtkContainer *)combo, result);
+
+            if (widget_type == COMBO_BOX_TEXT_FIELD)
+                (*fp_gtk_container_add)((GtkContainer *)combo, result);
+            else
+            {
+                (*fp_gtk_widget_set_parent)(result, combo);
+                ((GtkBin*)combo)->child = result;
+            }
+
             (*fp_gtk_container_add)((GtkContainer *)gtk2_fixed, combo);
             (*fp_gtk_widget_realize)(result);
             return result;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/swing/JEditorPane/bug4714674.java	Thu Apr 24 05:58:57 2008 -0700
@@ -0,0 +1,124 @@
+/* @test
+   @bug 4714674
+   @summary Tests that JEditorPane opens HTTP connection asynchronously
+   @author Peter Zhelezniakov
+   @run main bug4714674
+*/
+
+import javax.swing.*;
+
+import com.sun.net.httpserver.HttpExchange;
+import com.sun.net.httpserver.HttpHandler;
+import com.sun.net.httpserver.HttpServer;
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.util.concurrent.Executors;
+
+
+public class bug4714674 {
+
+    public static void main(String[] args) throws Exception {
+        new bug4714674().test();
+    }
+
+    private void test() throws Exception {
+        final DeafServer server = new DeafServer();
+        final String baseURL = "http://localhost:" + server.getPort() + "/";
+
+        SwingUtilities.invokeLater(new Runnable() {
+            public void run() {
+                try {
+                    JEditorPane pane = new JEditorPane();
+                    ((javax.swing.text.AbstractDocument)pane.getDocument()).
+                            setAsynchronousLoadPriority(1);
+
+                    // this will block EDT unless 4714674 is fixed
+                    pane.setPage(baseURL);
+                } catch (IOException e) {
+                    // should not happen
+                    throw new Error(e);
+                }
+            }
+        });
+
+        // if 4714674 is fixed, this executes before connection times out
+        SwingUtilities.invokeLater(new Runnable() {
+            public void run() {
+                synchronized (server) {
+                    server.wakeup = true;
+                    server.notifyAll();
+                }
+                pass();
+            }
+        });
+
+        // wait, then check test status
+        try {
+            Thread.sleep(5000);
+            if (!passed()) {
+                throw new RuntimeException("Failed: EDT was blocked");
+            }
+        } finally {
+            server.destroy();
+        }
+    }
+
+    private boolean passed = false;
+
+    private synchronized boolean passed() {
+        return passed;
+    }
+
+    private synchronized void pass() {
+        passed = true;
+    }
+}
+
+/**
+ * A "deaf" HTTP server that does not respond to requests.
+ */
+class DeafServer {
+    HttpServer server;
+    boolean wakeup = false;
+
+    /**
+     * Create and start the HTTP server.
+     */
+    public DeafServer() throws IOException {
+        InetSocketAddress addr = new InetSocketAddress(0);
+        server = HttpServer.create(addr, 0);
+        HttpHandler handler = new DeafHandler();
+        server.createContext("/", handler);
+        server.setExecutor(Executors.newCachedThreadPool());
+        server.start();
+    }
+
+    /**
+     * Stop server without any delay.
+     */
+    public void destroy() {
+        server.stop(0);
+    }
+
+    /**
+     * Return actual server port number, useful for constructing request URIs.
+     */
+    public int getPort() {
+        return server.getAddress().getPort();
+    }
+
+
+    class DeafHandler implements HttpHandler {
+        public void handle(HttpExchange r) throws IOException {
+            synchronized (DeafServer.this) {
+                while (! wakeup) {
+                    try {
+                        DeafServer.this.wait();
+                    } catch (InterruptedException e) {
+                        // just wait again
+                    }
+                }
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/swing/JPopupMenu/6675802/bug6675802.java	Thu Apr 24 05:58:57 2008 -0700
@@ -0,0 +1,43 @@
+/*
+ * Copyright 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.
+ *
+ * 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 6675802
+ * @summary Checks that there is no AccessControlException when
+ * a heaviweight popup menu is shown from an applet.
+ * @author Mikhail Lapshin
+ * @run main bug6675802
+ */
+
+import javax.swing.*;
+
+public class bug6675802 {
+    public static void main(String[] args) {
+        System.setSecurityManager(new SecurityManager());
+        final JPopupMenu popupMenu = new JPopupMenu();
+        popupMenu.add(new JMenuItem("Click"));
+        popupMenu.show(null, 0, 0);
+        System.out.println("Test passed");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/swing/JPopupMenu/6691503/bug6691503.java	Thu Apr 24 05:58:57 2008 -0700
@@ -0,0 +1,113 @@
+/*
+ * Copyright 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.
+ *
+ * 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 6691503
+ * @summary Checks that there is no opportunity for a malicious applet
+ * to show a popup menu which has whole screen size.
+ * a heaviweight popup menu is shown from an applet.
+ * @author Mikhail Lapshin
+ * @run main bug6691503
+ */
+
+import sun.awt.SunToolkit;
+
+import javax.swing.*;
+import java.awt.*;
+
+public class bug6691503 {
+    private JPopupMenu popupMenu;
+    private JFrame frame;
+    private boolean isAlwaysOnTop1 = false;
+    private boolean isAlwaysOnTop2 = true;
+
+    public static void main(String[] args) {
+        bug6691503 test = new bug6691503();
+        test.setupUI();
+        test.testApplication();
+        test.testApplet();
+        test.checkResult();
+        test.stopEDT();
+    }
+
+    private void setupUI() {
+        SwingUtilities.invokeLater(new Runnable() {
+            public void run() {
+                frame = new JFrame();
+                frame.setVisible(true);
+                popupMenu = new JPopupMenu();
+                JMenuItem click = new JMenuItem("Click");
+                popupMenu.add(click);
+            }
+        });
+    }
+
+    private void testApplication() {
+        SwingUtilities.invokeLater(new Runnable() {
+            public void run() {
+                popupMenu.show(frame, 0, 0);
+                Window popupWindow = (Window)
+                        (popupMenu.getParent().getParent().getParent().getParent());
+                isAlwaysOnTop1 = popupWindow.isAlwaysOnTop();
+                System.out.println(
+                        "Application: popupWindow.isAlwaysOnTop() = " + isAlwaysOnTop1);
+                popupMenu.setVisible(false);
+            }
+        });
+    }
+
+    private void testApplet() {
+        SwingUtilities.invokeLater(new Runnable() {
+            public void run() {
+                System.setSecurityManager(new SecurityManager());
+                popupMenu.show(frame, 0, 0);
+                Window popupWindow = (Window)
+                        (popupMenu.getParent().getParent().getParent().getParent());
+                isAlwaysOnTop2 = popupWindow.isAlwaysOnTop();
+                System.out.println(
+                        "Applet: popupWindow.isAlwaysOnTop() = " + isAlwaysOnTop2);
+                popupMenu.setVisible(false);
+            }
+        });
+    }
+
+    private void checkResult() {
+        ((SunToolkit)(Toolkit.getDefaultToolkit())).realSync();
+        if (!isAlwaysOnTop1 || isAlwaysOnTop2) {
+            throw new RuntimeException("Malicious applet can show always-on-top " +
+                    "popup menu which has whole screen size");
+        }
+        System.out.println("Test passed");
+    }
+
+    private void stopEDT() {
+        SwingUtilities.invokeLater(new Runnable() {
+            public void run() {
+                frame.dispose();
+            }
+        });
+    }
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/swing/JScrollPane/6612531/bug6612531.java	Thu Apr 24 05:58:57 2008 -0700
@@ -0,0 +1,42 @@
+/*
+ * Copyright 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.
+ *
+ * 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 6612531
+ * @summary Checks that ScrollPaneLayout.preferredLayoutSize() doesn't throw NPE.
+ * @author Mikhail Lapshin
+ * @run main bug6612531
+ */
+
+import javax.swing.*;
+
+public class bug6612531 {
+    public static void main(String[] args) {
+        ScrollPaneLayout c = new ScrollPaneLayout();
+        JViewport vp = new JViewport();
+        c.addLayoutComponent("VIEWPORT", vp);
+        c.preferredLayoutSize(new JScrollPane());
+        System.out.println("Test passed");
+    }
+}