Hi.
Roman Kennke wrote:
> Am Mittwoch, den 22.02.2006, 09:08 +0100 schrieb Robert Schuster:
>
>>Hi,
>>as mentioned in PR 26157[0] I observed that the JDK's JTextArea adjusts its
>>size
>>automatically when the characters leave the allocation area of the component.
>>Our JTextArea did not have this functionality until now.
>>
>>It took me a while to find out where to place the code that could do the
>>neccessary checks which should prevent unneeded revalidate() calls.
>>
>>While implementing this I found and fixed two problems in PlainView:
>>
>>1) The switch statement in getPreferredSpan always fell into the Y_AXIS case.
>>
>>2) In changeUpdate() the maxLineLength value could never shrink when
>>characters
>>are removed on one line only. I added a check whether the characters are
>>removed
>>from the current longest line and update the maxLineLength value if that is
>>the
>>case.
>
>
> Great!
>
> <<
> switch (axis)
> {
> case X_AXIS:
> - span = determineMaxLineLength();
> + return determineMaxLineLength();
> case Y_AXIS:
> default:
> - span = metrics.getHeight() * el.getElementCount();
> - break;
> + return metrics.getHeight() * el.getElementCount();
> }
> - return span;
>
Done so.
>
> - private class RootView extends View
> + class RootView extends View
>
Not neccessary any more.
>
> + /** Extends the RootView of BasicTextUI with the ability to adjust
> the size
> + * of the component after text was inserted, removed or changed.
> + */
> + class TextAreaRootView extends BasicTextUI.RootView
> + {
>
As explained on IRC I added the appropriate preferenceChanged() calls into
PlainView.
The new ChangeLog:
2006-02-21 Robert Schuster <[EMAIL PROTECTED]>
* javax/swing/text/PlainDocument.java:
(getPreferredSpan): Added missing 'break'.
statement which corrects an unwanted fall through.
(updateDamage): Update maxLineLength correctly when text is
removed, call preferenceChanged accordingly.
(viewToModel): Restrict line number to be within 0 and the
number of elements-1.
What is the last entry? A fix for a small problem I stepped upon when selecting
text with the mouse while hovering far above the component. I think it is a
minor glitch and the fix is appropriate that is why it is included in this
patch.
cya
Robert
Index: javax/swing/text/PlainView.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/text/PlainView.java,v
retrieving revision 1.36
diff -u -r1.36 PlainView.java
--- javax/swing/text/PlainView.java 8 Feb 2006 15:57:41 -0000 1.36
+++ javax/swing/text/PlainView.java 22 Feb 2006 09:48:51 -0000
@@ -307,18 +307,20 @@
// make sure we have the metrics
updateMetrics();
- float span = 0;
Element el = getElement();
+ float span;
switch (axis)
{
case X_AXIS:
span = determineMaxLineLength();
+ break;
case Y_AXIS:
default:
span = metrics.getHeight() * el.getElementCount();
break;
}
+
return span;
}
@@ -341,12 +343,19 @@
Element root = doc.getDefaultRootElement();
// PlainView doesn't support line-wrapping so we can find out which
- // Element was clicked on just by the y-position
- int lineClicked = (int) (y - rec.y) / metrics.getHeight();
- if (lineClicked >= root.getElementCount())
- return getEndOffset() - 1;
+ // Element was clicked on just by the y-position.
+ // Since the coordinates may be outside of the coordinate space
+ // of the allocation area (e.g. user dragged mouse outside
+ // the component) we have to limit the values.
+ // This has the nice effect that the user can drag the
+ // mouse above or below the component and it will still
+ // react to the x values (e.g. when selecting).
+ int lineClicked
+ = Math.min(Math.max((int) (y - rec.y) / metrics.getHeight(), 0),
+ root.getElementCount() - 1);
Element line = root.getElement(lineClicked);
+
Segment s = getLineBuffer();
int start = line.getStartOffset();
// We don't want the \n at the end of the line.
@@ -376,6 +385,8 @@
*/
protected void updateDamage(DocumentEvent changes, Shape a, ViewFactory f)
{
+ float oldMaxLineLength = maxLineLength;
+ Rectangle alloc = a.getBounds();
Element el = getElement();
ElementChange ec = changes.getChange(el);
@@ -383,7 +394,19 @@
// repaint the changed line
if (ec == null)
{
- int line = getElement().getElementIndex(changes.getOffset());
+ int line = el.getElementIndex(changes.getOffset());
+
+ // If characters have been removed from the current longest line
+ // we have to find out which one is the longest now otherwise
+ // the preferred x-axis span will not shrink.
+ if (changes.getType() == DocumentEvent.EventType.REMOVE
+ && el.getElement(line) == longestLine)
+ {
+ maxLineLength = -1;
+ if (determineMaxLineLength() != alloc.width)
+ preferenceChanged(this, true, false);
+ }
+
damageLineRange(line, line, a, getContainer());
return;
}
@@ -396,12 +419,13 @@
if (removed == null && newElements == null)
{
int line = getElement().getElementIndex(changes.getOffset());
+
damageLineRange(line, line, a, getContainer());
return;
}
// Check to see if we removed the longest line, if so we have to
- // search through all lines and find the longest one again
+ // search through all lines and find the longest one again.
if (removed != null)
{
for (int i = 0; i < removed.length; i++)
@@ -409,8 +433,11 @@
{
// reset maxLineLength and search through all lines for longest one
maxLineLength = -1;
- determineMaxLineLength();
+ if (determineMaxLineLength() != alloc.width)
+ preferenceChanged(this, true, removed.length != newElements.length);
+
((JTextComponent)getContainer()).repaint();
+
return;
}
}
@@ -420,6 +447,7 @@
{
// No lines were added, just repaint the container and exit
((JTextComponent)getContainer()).repaint();
+
return;
}
@@ -468,6 +496,14 @@
maxLineLength = longestNewLength;
longestLine = longestNewLine;
}
+
+ // Report any changes to the preferred sizes of the view
+ // which may cause the underlying component to be revalidated.
+ boolean widthChanged = oldMaxLineLength != maxLineLength;
+ boolean heightChanged = removed.length != newElements.length;
+ if (widthChanged || heightChanged)
+ preferenceChanged(this, widthChanged, heightChanged);
+
// Repaint the container
((JTextComponent)getContainer()).repaint();
}
signature.asc
Description: OpenPGP digital signature
