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()