aboutsummaryrefslogtreecommitdiff
path: root/libjava/classpath/javax/swing/text/PlainView.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/javax/swing/text/PlainView.java')
-rw-r--r--libjava/classpath/javax/swing/text/PlainView.java233
1 files changed, 121 insertions, 112 deletions
diff --git a/libjava/classpath/javax/swing/text/PlainView.java b/libjava/classpath/javax/swing/text/PlainView.java
index 18818c0..48fe37c 100644
--- a/libjava/classpath/javax/swing/text/PlainView.java
+++ b/libjava/classpath/javax/swing/text/PlainView.java
@@ -437,132 +437,92 @@ public class PlainView extends View implements TabExpander
*/
protected void updateDamage(DocumentEvent changes, Shape a, ViewFactory f)
{
- // Return early and do no updates if the allocation area is null
- // (like the RI).
- if (a == null)
- return;
-
- float oldMaxLineLength = maxLineLength;
- Rectangle alloc = a.getBounds();
- Element el = getElement();
- ElementChange ec = changes.getChange(el);
-
- // If ec is null then no lines were added or removed, just
- // repaint the changed line
- if (ec == null)
- {
- 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;
- }
-
- Element[] removed = ec.getChildrenRemoved();
- Element[] newElements = ec.getChildrenAdded();
-
- // If no Elements were added or removed, we just want to repaint
- // the area containing the line that was modified
- if (removed == null && newElements == null)
+ // This happens during initialization.
+ if (metrics == null)
{
- int line = getElement().getElementIndex(changes.getOffset());
-
- damageLineRange(line, line, a, getContainer());
+ updateMetrics();
+ preferenceChanged(null, true, true);
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.
- if (removed != null)
- {
- for (int i = 0; i < removed.length; i++)
- if (removed[i].equals(longestLine))
- {
- // reset maxLineLength and search through all lines for longest one
- maxLineLength = -1;
- if (determineMaxLineLength() != alloc.width)
- preferenceChanged(this, true, removed.length != newElements.length);
-
- ((JTextComponent)getContainer()).repaint();
-
- return;
- }
- }
-
- // If we've reached here, that means we haven't removed the longest line
- if (newElements == null)
- {
- // No lines were added, just repaint the container and exit
- ((JTextComponent)getContainer()).repaint();
-
- return;
- }
+ Element element = getElement();
- // Make sure we have the metrics
- updateMetrics();
-
- // If we've reached here, that means we haven't removed the longest line
- // and we have added at least one line, so we have to check if added lines
- // are longer than the previous longest line
- Segment seg = getLineBuffer();
- float longestNewLength = 0;
- Element longestNewLine = null;
+ // Find longest line if it hasn't been initialized yet.
+ if (longestLine == null)
+ findLongestLine(0, element.getElementCount() - 1);
- // Loop through the added lines to check their length
- for (int i = 0; i < newElements.length; i++)
+ ElementChange change = changes.getChange(element);
+ if (changes.getType() == DocumentEvent.EventType.INSERT)
{
- Element child = newElements[i];
- int start = child.getStartOffset();
- int end = child.getEndOffset() - 1;
- try
- {
- el.getDocument().getText(start, end - start, seg);
- }
- catch (BadLocationException ex)
+ // Handles character/line insertion.
+
+ // Determine if lines have been added. In this case we repaint
+ // differently.
+ boolean linesAdded = true;
+ if (change == null)
+ linesAdded = false;
+
+ // Determine the start line.
+ int start;
+ if (linesAdded)
+ start = change.getIndex();
+ else
+ start = element.getElementIndex(changes.getOffset());
+
+ // Determine the length of the updated region.
+ int length = 0;
+ if (linesAdded)
+ length = change.getChildrenAdded().length - 1;
+
+ // Update the longest line and length.
+ int oldMaxLength = (int) maxLineLength;
+ if (longestLine.getEndOffset() < changes.getOffset()
+ || longestLine.getStartOffset() > changes.getOffset()
+ + changes.getLength())
{
- AssertionError ae = new AssertionError("Unexpected bad location");
- ae.initCause(ex);
- throw ae;
+ findLongestLine(start, start + length);
}
-
- if (seg == null || seg.array == null || seg.count == 0)
- continue;
-
- int width = metrics.charsWidth(seg.array, seg.offset, seg.count);
- if (width > longestNewLength)
+ else
{
- longestNewLine = child;
- longestNewLength = width;
+ findLongestLine(0, element.getElementCount() - 1);
}
+
+ // Trigger a preference change so that the layout gets updated
+ // correctly.
+ preferenceChanged(null, maxLineLength != oldMaxLength, linesAdded);
+
+ // Damage the updated line range.
+ int endLine = start;
+ if (linesAdded)
+ endLine = element.getElementCount() - 1;
+ damageLineRange(start, endLine, a, getContainer());
+
}
-
- // Check if the longest of the new lines is longer than our previous
- // longest line, and if so update our values
- if (longestNewLength > maxLineLength)
+ else
{
- maxLineLength = longestNewLength;
- longestLine = longestNewLine;
+ // Handles character/lines removals.
+
+ // Update the longest line and length and trigger preference changed.
+ int oldMaxLength = (int) maxLineLength;
+ if (change != null)
+ {
+ // Line(s) have been removed.
+ findLongestLine(0, element.getElementCount() - 1);
+ preferenceChanged(null, maxLineLength != oldMaxLength, true);
+ }
+ else
+ {
+ // No line has been removed.
+ int lineNo = getElement().getElementIndex(changes.getOffset());
+ Element line = getElement().getElement(lineNo);
+ if (longestLine == line)
+ {
+ findLongestLine(0, element.getElementCount() - 1);
+ preferenceChanged(null, maxLineLength != oldMaxLength, false);
+ }
+ damageLineRange(lineNo, lineNo, a, getContainer());
+ }
}
-
- // 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();
}
/**
@@ -648,5 +608,54 @@ public class PlainView extends View implements TabExpander
lineBuffer = new Segment();
return lineBuffer;
}
+
+ /**
+ * Finds and updates the longest line in the view inside an interval of
+ * lines.
+ *
+ * @param start the start of the search interval
+ * @param end the end of the search interval
+ */
+ private void findLongestLine(int start, int end)
+ {
+ for (int i = start; i <= end; i++)
+ {
+ int w = getLineLength(i);
+ if (w > maxLineLength)
+ {
+ maxLineLength = w;
+ longestLine = getElement().getElement(i);
+ }
+ }
+ }
+
+ /**
+ * Determines the length of the specified line.
+ *
+ * @param line the number of the line
+ *
+ * @return the length of the line in pixels
+ */
+ private int getLineLength(int line)
+ {
+ Element lineEl = getElement().getElement(line);
+ Segment buffer = getLineBuffer();
+ try
+ {
+ Document doc = getDocument();
+ doc.getText(lineEl.getStartOffset(),
+ lineEl.getEndOffset() - lineEl.getStartOffset() - 1,
+ buffer);
+ }
+ catch (BadLocationException ex)
+ {
+ AssertionError err = new AssertionError("Unexpected bad location");
+ err.initCause(ex);
+ throw err;
+ }
+
+ return Utilities.getTabbedTextWidth(buffer, metrics, 0, this,
+ lineEl.getStartOffset());
+ }
}