From 2fde30e51e365eb4eeaf9de48a5054b4a67daa2e Mon Sep 17 00:00:00 2001 From: peterz Date: Thu, 3 Apr 2008 16:41:43 +0400 Subject: 4714674: JEditorPane.setPage(url) blocks AWT thread when HTTP protocol is used Summary: Both POST and GET can now be processed asynchronously; PageLoader refactored Reviewed-by: gsm --- src/share/classes/javax/swing/JEditorPane.java | 125 ++++++------------------- 1 file changed, 31 insertions(+), 94 deletions(-) (limited to 'src/share/classes/javax/swing') diff --git a/src/share/classes/javax/swing/JEditorPane.java b/src/share/classes/javax/swing/JEditorPane.java index 839507529..4cf18c009 100644 --- a/src/share/classes/javax/swing/JEditorPane.java +++ b/src/share/classes/javax/swing/JEditorPane.java @@ -429,9 +429,8 @@ public class JEditorPane extends JTextComponent { // 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 @@ public class JEditorPane extends JTextComponent { // 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 @@ public class JEditorPane extends JTextComponent { 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 @@ public class JEditorPane extends JTextComponent { /** - * 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 { /** * 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 loading 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 @@ public class JEditorPane extends JTextComponent { } 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 @@ public class JEditorPane extends JTextComponent { } catch (IOException ioe) { UIManager.getLookAndFeel().provideErrorFeedback(JEditorPane.this); } finally { - synchronized(JEditorPane.this) { - loading = null; - } - SwingUtilities.invokeLater(new Runnable() { - public void run() { - if (pageLoaded) { - firePropertyChange("page", old, page); + if (pageLoaded) { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + JEditorPane.this.firePropertyChange("page", old, page); } - } - }); + }); + } + return (pageLoaded ? page : old); } } @@ -718,51 +704,6 @@ public class JEditorPane extends JTextComponent { 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 setPage method. By @@ -1573,11 +1514,7 @@ public class JEditorPane extends JTextComponent { // --- variables --------------------------------------- - /** - * Stream currently loading asynchronously (potentially cancelable). - * Access to this variable should be synchronized. - */ - PageStream loading; + private SwingWorker pageLoader; /** * Current content binding of the editor. -- cgit v1.2.3 From 4a8b67711c5195f2b51e522f656fa2eaefc4844a Mon Sep 17 00:00:00 2001 From: peterz Date: Mon, 7 Apr 2008 13:07:04 +0400 Subject: 4765383: JTextArea.append(String) not thread safe Summary: Several swing.text methods are not marked thread-safe anymore. Reviewed-by: gsm --- src/share/classes/javax/swing/JEditorPane.java | 10 -------- src/share/classes/javax/swing/JTextArea.java | 15 ----------- src/share/classes/javax/swing/JTextPane.java | 30 ---------------------- .../classes/javax/swing/text/JTextComponent.java | 11 +------- 4 files changed, 1 insertion(+), 65 deletions(-) (limited to 'src/share/classes/javax/swing') diff --git a/src/share/classes/javax/swing/JEditorPane.java b/src/share/classes/javax/swing/JEditorPane.java index 4cf18c009..c126fe70c 100644 --- a/src/share/classes/javax/swing/JEditorPane.java +++ b/src/share/classes/javax/swing/JEditorPane.java @@ -1120,11 +1120,6 @@ public class JEditorPane extends JTextComponent { * current selection. The replacement text will have the * attributes currently defined for input. If the component is not * editable, beep and return. - *

- * This method is thread safe, although most Swing methods - * are not. Please see - * How - * to Use Threads for more information. * * @param content the content to replace the selection with. This * value can be null @@ -1395,11 +1390,6 @@ public class JEditorPane extends JTextComponent { * 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. - *

- * This method is thread safe, although most Swing methods - * are not. Please see - * How - * to Use Threads for more information. * * @param t the new text to be set; if null the old * text will be deleted diff --git a/src/share/classes/javax/swing/JTextArea.java b/src/share/classes/javax/swing/JTextArea.java index 8f53daf2a..f7718198b 100644 --- a/src/share/classes/javax/swing/JTextArea.java +++ b/src/share/classes/javax/swing/JTextArea.java @@ -444,11 +444,6 @@ public class JTextArea extends JTextComponent { /** * Inserts the specified text at the specified position. Does nothing * if the model is null or if the text is null or empty. - *

- * This method is thread safe, although most Swing methods - * are not. Please see - * How - * to Use Threads for more information. * * @param str the text to insert * @param pos the position at which to insert >= 0 @@ -471,11 +466,6 @@ public class JTextArea extends JTextComponent { /** * Appends the given text to the end of the document. Does nothing if * the model is null or the string is null or empty. - *

- * This method is thread safe, although most Swing methods - * are not. Please see - * How - * to Use Threads for more information. * * @param str the text to insert * @see #insert @@ -494,11 +484,6 @@ public class JTextArea extends JTextComponent { * 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. - *

- * This method is thread safe, although most Swing methods - * are not. Please see - * How - * to Use Threads for more information. * * @param str the text to use as the replacement * @param start the start position >= 0 diff --git a/src/share/classes/javax/swing/JTextPane.java b/src/share/classes/javax/swing/JTextPane.java index 69b94a30e..c820f512d 100644 --- a/src/share/classes/javax/swing/JTextPane.java +++ b/src/share/classes/javax/swing/JTextPane.java @@ -167,11 +167,6 @@ public class JTextPane extends JEditorPane { * 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. - *

- * This method is thread safe, although most Swing methods - * are not. Please see - * How - * to Use Threads for more information. * * @param content the content to replace the selection with */ @@ -229,11 +224,6 @@ public class JTextPane extends JEditorPane { * a value of 0.75 will cause 75 percent of the * component to be above the baseline, and 25 percent of the * component to be below the baseline. - *

- * This method is thread safe, although most Swing methods - * are not. Please see - * How - * to Use Threads for more information. * * @param c the component to insert */ @@ -252,11 +242,6 @@ public class JTextPane extends JEditorPane { * current position of the caret. This is represented in * the associated document as an attribute of one character * of content. - *

- * This method is thread safe, although most Swing methods - * are not. Please see - * How - * to Use Threads for more information. * * @param g the icon to insert * @see Icon @@ -320,11 +305,6 @@ public class JTextPane extends JEditorPane { * 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. - *

- * This method is thread safe, although most Swing methods - * are not. Please see - * How - * to Use Threads for more information. * * @param s the logical style to assign to the paragraph, * or null for no style @@ -367,11 +347,6 @@ public class JTextPane extends JEditorPane { * is no selection, the attributes are applied to * the input attribute set which defines the attributes * for any new text that gets inserted. - *

- * This method is thread safe, although most Swing methods - * are not. Please see - * How - * to Use Threads for more information. * * @param attr the attributes * @param replace if true, then replace the existing attributes first @@ -412,11 +387,6 @@ public class JTextPane extends JEditorPane { * to the paragraphs that intersect the selection. * If there is no selection, the attributes are applied * to the paragraph at the current caret position. - *

- * This method is thread safe, although most Swing methods - * are not. Please see - * How - * to Use Threads for more information. * * @param attr the non-null attributes * @param replace if true, replace the existing attributes first diff --git a/src/share/classes/javax/swing/text/JTextComponent.java b/src/share/classes/javax/swing/text/JTextComponent.java index 9ba898956..d340f281e 100644 --- a/src/share/classes/javax/swing/text/JTextComponent.java +++ b/src/share/classes/javax/swing/text/JTextComponent.java @@ -1349,11 +1349,6 @@ public abstract class JTextComponent extends JComponent implements Scrollable, A * This is the method that is used by the default implementation * of the action for inserting content that gets bound to the * keymap actions. - *

- * This method is thread safe, although most Swing methods - * are not. Please see - * How - * to Use Threads for more information. * * @param content the content to replace the selection with */ @@ -1687,12 +1682,8 @@ public abstract class JTextComponent extends JComponent implements Scrollable, A * 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. - *

- * This method is thread safe, although most Swing methods - * are not. Please see - * How - * to Use Threads for more information. * + *

* Note that text is not a bound property, so no PropertyChangeEvent * is fired when it changes. To listen for changes to the text, * use DocumentListener. -- cgit v1.2.3 From bae564c16677c3e2d00a9de0b46a9813f5d5a409 Mon Sep 17 00:00:00 2001 From: mlapshin Date: Mon, 14 Apr 2008 16:41:00 +0400 Subject: 6612531: api/javax_swing/ScrollPaneLayout/index.html#xxxLayoutSize (ScrollPaneLayout2024) throws NPE Summary: Added a check for the NPE Reviewed-by: alexp --- src/share/classes/javax/swing/ScrollPaneLayout.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/share/classes/javax/swing') diff --git a/src/share/classes/javax/swing/ScrollPaneLayout.java b/src/share/classes/javax/swing/ScrollPaneLayout.java index 34aa1cae6..ed769a929 100644 --- a/src/share/classes/javax/swing/ScrollPaneLayout.java +++ b/src/share/classes/javax/swing/ScrollPaneLayout.java @@ -488,10 +488,14 @@ public class ScrollPaneLayout 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. -- cgit v1.2.3 From fc0854bc0df74df00a2cf4d84af281b7e215d63d Mon Sep 17 00:00:00 2001 From: mlapshin Date: Fri, 18 Apr 2008 18:21:02 +0400 Subject: 6675802: Regression: heavyweight popups cause SecurityExceptions in applets Summary: The problem code in Popup class is surrounded by AccessController.doPrivileged() Reviewed-by: alexp --- src/share/classes/javax/swing/Popup.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src/share/classes/javax/swing') diff --git a/src/share/classes/javax/swing/Popup.java b/src/share/classes/javax/swing/Popup.java index 02ab11610..b246b67f4 100644 --- a/src/share/classes/javax/swing/Popup.java +++ b/src/share/classes/javax/swing/Popup.java @@ -229,7 +229,14 @@ public class Popup { // Popups are typically transient and most likely won't benefit // from true double buffering. Turn it off here. getRootPane().setUseTrueDoubleBuffering(false); - setAlwaysOnTop(true); + java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Object run() { + setAlwaysOnTop(true); + return null; + } + } + ); } public void update(Graphics g) { -- cgit v1.2.3 From d892b43350765e08c8eb5e7044a427459042fddb Mon Sep 17 00:00:00 2001 From: mlapshin Date: Wed, 23 Apr 2008 18:06:34 +0400 Subject: 6691503: Malicious applet can show always-on-top popup menu which has whole screen size Summary: The fix for 6675802 is replaced by a try-catch clause that catches SequrityExceptions for applets. Reviewed-by: alexp --- src/share/classes/javax/swing/Popup.java | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'src/share/classes/javax/swing') diff --git a/src/share/classes/javax/swing/Popup.java b/src/share/classes/javax/swing/Popup.java index b246b67f4..a6373f87b 100644 --- a/src/share/classes/javax/swing/Popup.java +++ b/src/share/classes/javax/swing/Popup.java @@ -229,14 +229,15 @@ public class Popup { // Popups are typically transient and most likely won't benefit // from true double buffering. Turn it off here. getRootPane().setUseTrueDoubleBuffering(false); - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { - setAlwaysOnTop(true); - return null; - } - } - ); + // 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) { -- cgit v1.2.3