This fixes/enables scrolling for JEditorPane.

2006-08-31  Roman Kennke  <[EMAIL PROTECTED]>

        * javax/swing/JEditorPane.java
        (getPreferredSize): Replace preferred size with minimum
        UI size only if the scrollable does _not_ track the viewport
        size and only if the viewport's size is smaller than the
        scrollable's size.
        (getScrollableTracksViewportWidth): Avoid unnecessary multiple
        method calls.
        * javax/swing/plaf/basic/BasicTextUI.java
        (getPreferredSize): Read-lock the document to avoid
        concurrency problems.
        (getMaximumSize): Return maximum size of the view.
        Read-lock the document to avoid concurrency problems.
        (getMinimumSize): Return minimum size of the view.
        Read-lock the document to avoid concurrency problems.

/Roman
Index: javax/swing/plaf/basic/BasicTextUI.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/plaf/basic/BasicTextUI.java,v
retrieving revision 1.93
diff -u -1 -2 -r1.93 BasicTextUI.java
--- javax/swing/plaf/basic/BasicTextUI.java	29 Aug 2006 10:57:17 -0000	1.93
+++ javax/swing/plaf/basic/BasicTextUI.java	31 Aug 2006 15:24:13 -0000
@@ -364,25 +364,25 @@
 
     /**
      * Returns the preferred span along the specified <code>axis</code>.
      * This is delegated to the real root view.
      *
      * @param axis the axis for which the preferred span is queried
      *
      * @return the preferred span along the axis
      */
     public float getPreferredSpan(int axis)
     {
       if (view != null)
-	return view.getPreferredSpan(axis);
+        return view.getPreferredSpan(axis);
 
       return Integer.MAX_VALUE;
     }
 
     public void setSize(float w, float h)
     {
       if (view != null)
         view.setSize(w, h);
     }
 
     /**
      * Paints the view. This is delegated to the real root view.
@@ -956,62 +956,112 @@
 
   /**
    * Returns the preferred size of the text component.
    *
    * @param c not used here
    *
    * @return the preferred size of the text component
    */
   public Dimension getPreferredSize(JComponent c)
   {
     Dimension d = c.getSize();
     Insets i = c.getInsets();
-    if (d.width > (i.left + i.right) && d.height > (i.top + i.bottom))
+    // We need to lock here, since we require the view hierarchy to _not_
+    // change in between.
+    float w;
+    float h;
+    Document doc = textComponent.getDocument();
+    if (doc instanceof AbstractDocument)
+      ((AbstractDocument) doc).readLock();
+    try
       {
-        rootView.setSize(d.width - i.left - i.right,
-                         d.height - i.top - i.bottom);
+        if (d.width > (i.left + i.right) && d.height > (i.top + i.bottom))
+          {
+            rootView.setSize(d.width - i.left - i.right,
+                             d.height - i.top - i.bottom);
+          }
+        w = rootView.getPreferredSpan(View.X_AXIS);
+        h = rootView.getPreferredSpan(View.Y_AXIS);
+      }
+    finally
+      {
+        if (doc instanceof AbstractDocument)
+          ((AbstractDocument) doc).readUnlock();
       }
-    float w = rootView.getPreferredSpan(View.X_AXIS);
-    float h = rootView.getPreferredSpan(View.Y_AXIS);
-
     Dimension size =  new Dimension((int) w + i.left + i.right,
                          (int) h + i.top + i.bottom);
     return size;
   }
 
   /**
    * Returns the maximum size for text components that use this UI.
    *
    * This returns (Integer.MAX_VALUE, Integer.MAX_VALUE).
    *
    * @param c not used here
    *
    * @return the maximum size for text components that use this UI
    */
   public Dimension getMaximumSize(JComponent c)
   {
-    // Sun's implementation returns Integer.MAX_VALUE here, so do we.
-    return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
+    Dimension d = new Dimension();
+    Document doc = textComponent.getDocument();
+    // We need to lock here, since we require the view hierarchy to _not_
+    // change in between.
+    if (doc instanceof AbstractDocument)
+      ((AbstractDocument) doc).readLock();
+    try
+      {
+        d.width = (int) rootView.getMaximumSpan(View.X_AXIS);
+        d.height = (int) rootView.getMaximumSpan(View.Y_AXIS);
+      }
+    finally
+      {
+        if (doc instanceof AbstractDocument)
+          ((AbstractDocument) doc).readUnlock();
+      }
+    Insets i = c.getInsets();
+    d.width += i.left + i.right;
+    d.height += i.top + i.bottom;
+    return d;
   }
 
   /**
    * Returns the minimum size for text components. This returns the size
    * of the component's insets.
    *
    * @return the minimum size for text components
    */
   public Dimension getMinimumSize(JComponent c)
   {
+    Dimension d = new Dimension();
+    Document doc = textComponent.getDocument();
+    // We need to lock here, since we require the view hierarchy to _not_
+    // change in between.
+    if (doc instanceof AbstractDocument)
+      ((AbstractDocument) doc).readLock();
+    try
+      {
+        d.width = (int) rootView.getMinimumSpan(View.X_AXIS);
+        d.height = (int) rootView.getMinimumSpan(View.Y_AXIS);
+      }
+    finally
+      {
+        if (doc instanceof AbstractDocument)
+          ((AbstractDocument) doc).readUnlock();
+      }
     Insets i = c.getInsets();
-    return new Dimension(i.left + i.right, i.top + i.bottom);
+    d.width += i.left + i.right;
+    d.height += i.top + i.bottom;
+    return d;
   }
 
   /**
    * Paints the text component. This acquires a read lock on the model and then
    * calls [EMAIL PROTECTED] #paintSafely(Graphics)} in order to actually perform the
    * painting.
    *
    * @param g the <code>Graphics</code> context to paint to
    * @param c not used here
    */
   public final void paint(Graphics g, JComponent c)
   {
Index: javax/swing/JEditorPane.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/JEditorPane.java,v
retrieving revision 1.34
diff -u -1 -2 -r1.34 JEditorPane.java
--- javax/swing/JEditorPane.java	12 Aug 2006 22:16:12 -0000	1.34
+++ javax/swing/JEditorPane.java	31 Aug 2006 15:24:13 -0000
@@ -47,24 +47,25 @@
 import java.io.StringReader;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.HashMap;
 
 import javax.accessibility.AccessibleContext;
 import javax.accessibility.AccessibleHyperlink;
 import javax.accessibility.AccessibleHypertext;
 import javax.accessibility.AccessibleStateSet;
 import javax.accessibility.AccessibleText;
 import javax.swing.event.HyperlinkEvent;
 import javax.swing.event.HyperlinkListener;
+import javax.swing.plaf.TextUI;
 import javax.swing.text.BadLocationException;
 import javax.swing.text.DefaultEditorKit;
 import javax.swing.text.Document;
 import javax.swing.text.EditorKit;
 import javax.swing.text.Element;
 import javax.swing.text.JTextComponent;
 import javax.swing.text.View;
 import javax.swing.text.ViewFactory;
 import javax.swing.text.WrappedPlainView;
 import javax.swing.text.html.HTML;
 import javax.swing.text.html.HTMLDocument;
 import javax.swing.text.html.HTMLEditorKit;
@@ -686,48 +687,68 @@
    * Returns the preferred size for the JEditorPane. This is implemented to
    * return the super's preferred size, unless one of
    * [EMAIL PROTECTED] #getScrollableTracksViewportHeight()} or
    * [EMAIL PROTECTED] #getScrollableTracksViewportWidth()} returns <code>true</code>,
    * in which case the preferred width and/or height is replaced by the UI's
    * minimum size.
    *
    * @return the preferred size for the JEditorPane
    */
   public Dimension getPreferredSize()
   {
     Dimension pref = super.getPreferredSize();
-    if (getScrollableTracksViewportWidth())
-      pref.width = getUI().getMinimumSize(this).width;
-    if (getScrollableTracksViewportHeight())
-      pref.height = getUI().getMinimumSize(this).height;
+    Container parent = getParent();
+    if (parent instanceof JViewport)
+      {
+        JViewport vp = (JViewport) getParent();
+        TextUI ui = getUI();
+        Dimension min = null;
+        if (! getScrollableTracksViewportWidth())
+          {
+            min = ui.getMinimumSize(this);
+            int vpWidth = vp.getWidth();
+            if (vpWidth != 0 && vpWidth < min.width)
+              pref.width = min.width;
+          }
+        if (! getScrollableTracksViewportHeight())
+          {
+            if (min == null)
+              min = ui.getMinimumSize(this);
+            int vpHeight = vp.getHeight();
+            if (vpHeight != 0 && vpHeight < min.height)
+              pref.height = min.height;
+          }
+      }
     return pref;
   }
 
   /**
    * Returns <code>true</code> when a Viewport should force the height of
    * this component to match the viewport height. This is implemented to return
    * <code>true</code> when  the parent is an instance of JViewport and
    * the viewport height > the UI's minimum height.
    *
    * @return <code>true</code> when a Viewport should force the height of
    *         this component to match the viewport height
    */
   public boolean getScrollableTracksViewportHeight()
   {
     // Tests show that this returns true when the parent is a JViewport
     // and has a height > minimum UI height.
     Container parent = getParent();
+    int height = parent.getHeight();
+    TextUI ui = getUI();
     return parent instanceof JViewport
-           && parent.getHeight() >= getUI().getMinimumSize(this).height
-           && parent.getHeight() <= getUI().getMaximumSize(this).height;
+           && height >= ui.getMinimumSize(this).height
+           && height <= ui.getMaximumSize(this).height;
   }
 
   /**
    * Returns <code>true</code> when a Viewport should force the width of
    * this component to match the viewport width. This is implemented to return
    * <code>true</code> when  the parent is an instance of JViewport and
    * the viewport width > the UI's minimum width.
    *
    * @return <code>true</code> when a Viewport should force the width of
    *         this component to match the viewport width
    */
   public boolean getScrollableTracksViewportWidth()

Reply via email to