Hi, this fixes another bunch of problems with WrappedPlainView. There were all kinds of oddities which I have described in PR26676[0] and these are now fixed.
Included is a fix to Utilities.getTabbedTextOffset() which makes this method a bit more eager to break text. I changed a comparison from > to >= and now lines are not only broken when a character exceeds a certain x coordinate but even when it lies exactly on it. This has the effect that lines will not end exactly on the right edge of a textfield/textarea any more. IMHO this is how the JDK does things. ChangeLog: 2006-04-02 Robert Schuster <[EMAIL PROTECTED]> PR #26676 * javax/swing/text/Utilities.java: (getTabbedTextOffset): Added check to decrement pos not below zero, changed '>' comparison to '>='. * javax/swing/text/WrappedPlainView.java: (lineHeight): New field. (calculateBreakPosition): Throw InternalError in catch block, removed unneeded brackets, use specific version of Utilities.getTabbedTextOffset. (paint): Set various properties neccessary for drawing. (WrappedLine.paint): Removed code to set field of outer class. (WrappedLine.modelToView): Removed unneeded expression from if-statement. (WrappedLine.viewToModel): Initialize end with endOffset - 1, removed -1 from return statement, copy only a subset into the Segment, removed special handling of mark value - just return it, simplified incrementation of currLineStart. (WrappedLine.insertUpdate): Recalculate numLines, report preference change to parent view. (WrappedLine.removeUpdate): Dito. cya Robert [0] - http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26676
Index: javax/swing/text/Utilities.java =================================================================== RCS file: /cvsroot/classpath/classpath/javax/swing/text/Utilities.java,v retrieving revision 1.28 diff -u -r1.28 Utilities.java --- javax/swing/text/Utilities.java 1 Apr 2006 15:22:07 -0000 1.28 +++ javax/swing/text/Utilities.java 1 Apr 2006 22:44:03 -0000 @@ -238,14 +238,14 @@ // At the end of the for loop, this holds the requested model location int pos; int currentX = x0; - + for (pos = 0; pos < s.count; pos++) { char nextChar = s.array[s.offset+pos]; if (nextChar == 0) { - if (! round) + if (! round && pos > 0) pos--; break; } @@ -259,14 +259,13 @@ currentX = (int) te.nextTabStop(currentX, pos); } - if (currentX > x) + if (currentX >= x) { - if (! round) + if (! round && pos > 0) pos--; break; } } - return pos + p0; } Index: javax/swing/text/WrappedPlainView.java =================================================================== RCS file: /cvsroot/classpath/classpath/javax/swing/text/WrappedPlainView.java,v retrieving revision 1.14 diff -u -r1.14 WrappedPlainView.java --- javax/swing/text/WrappedPlainView.java 1 Apr 2006 15:22:07 -0000 1.14 +++ javax/swing/text/WrappedPlainView.java 1 Apr 2006 22:44:03 -0000 @@ -81,6 +81,9 @@ /** The end of the selected text **/ int selectionEnd; + /** The height of the line (used while painting) **/ + int lineHeight; + /** * The instance returned by [EMAIL PROTECTED] #getLineBuffer()}. */ @@ -274,6 +277,7 @@ Container c = getContainer(); Rectangle alloc = new Rectangle(0, 0, getWidth(), getHeight()); updateMetrics(); + try { getDocument().getText(p0, p1 - p0, getLineBuffer()); @@ -281,18 +285,16 @@ catch (BadLocationException ble) { // this shouldn't happen + throw new InternalError("Invalid offsets p0: " + p0 + " - p1: " + p1); } // FIXME: Should we account for the insets of the container? if (wordWrap) - return p0 - + Utilities.getBreakLocation(lineBuffer, metrics, alloc.x, + return p0 + Utilities.getBreakLocation(lineBuffer, metrics, alloc.x, alloc.x + alloc.width, this, 0); else - { - return p0 - + Utilities.getTabbedTextOffset(lineBuffer, metrics, alloc.x, - alloc.x + alloc.width, this, 0); - } + return p0 + Utilities.getTabbedTextOffset(lineBuffer, metrics, alloc.x, + alloc.x + alloc.width, this, 0, + true); } void updateMetrics() @@ -385,9 +387,19 @@ public void paint(Graphics g, Shape a) { JTextComponent comp = (JTextComponent)getContainer(); + // Ensure metrics are up-to-date. + updateMetrics(); + selectionStart = comp.getSelectionStart(); selectionEnd = comp.getSelectionEnd(); - updateMetrics(); + + selectedColor = comp.getSelectedTextColor(); + unselectedColor = comp.getForeground(); + disabledColor = comp.getDisabledTextColor(); + selectedColor = comp.getSelectedTextColor(); + lineHeight = metrics.getHeight(); + g.setFont(comp.getFont()); + super.paint(g, a); } @@ -420,21 +432,7 @@ */ public void paint(Graphics g, Shape s) { - // Ensure metrics are up-to-date. - updateMetrics(); - JTextComponent textComponent = (JTextComponent) getContainer(); - - g.setFont(textComponent.getFont()); - selectedColor = textComponent.getSelectedTextColor(); - unselectedColor = textComponent.getForeground(); - disabledColor = textComponent.getDisabledTextColor(); - - // FIXME: this is a hack, for some reason textComponent.getSelectedColor - // was returning black, which is not visible against a black background - selectedColor = Color.WHITE; - Rectangle rect = s.getBounds(); - int lineHeight = metrics.getHeight(); int end = getEndOffset(); int currStart = getStartOffset(); @@ -532,7 +530,7 @@ // If pos is between currLineStart and currLineEnd then just find // the width of the text from currLineStart to pos and add that // to rect.x - if (pos >= currLineStart && pos < currLineEnd || pos == end - 1) + if (pos >= currLineStart && pos < currLineEnd) { try { @@ -576,12 +574,16 @@ Segment s = getLineBuffer(); Rectangle rect = a.getBounds(); int currLineStart = getStartOffset(); - int end = getEndOffset(); + + // WrappedLine does not represent the last possible offset in a line. + // So we should never return that offset. Behavior observed in the RI. + int end = getEndOffset() - 1; + int lineHeight = metrics.getHeight(); if (y < rect.y) return currLineStart; if (y > rect.y + rect.height) - return end - 1; + return end; // Note: rect.x and rect.width do not represent the width of painted // text but the area where text *may* be painted. This means the width @@ -596,32 +598,24 @@ { try { - getDocument().getText(currLineStart, end - currLineStart, s); + getDocument().getText(currLineStart, currLineEnd - currLineStart, s); } catch (BadLocationException ble) { // Shouldn't happen } - int mark = Utilities.getTabbedTextOffset(s, metrics, rect.x, + return Utilities.getTabbedTextOffset(s, metrics, rect.x, (int) x, WrappedPlainView.this, currLineStart); - - // WrappedPlainView does not represent the last possible offset - // in the document. Se we should never return that offset. - // Behavior observed in the RI. - return (mark == end) ? end - 1 : mark; } // Increment rect.y so we're checking the next logical line rect.y += lineHeight; // Increment currLineStart to the model position of the start // of the next logical line - if (currLineEnd == currLineStart) - currLineStart = end; - else - currLineStart = currLineEnd; + currLineStart = currLineEnd; } } @@ -655,6 +649,11 @@ */ public void insertUpdate (DocumentEvent changes, Shape a, ViewFactory f) { + int oldNumLines = numLines; + determineNumLines(); + if (oldNumLines != numLines) + getParent().preferenceChanged(this, false, true); + updateDamage((Rectangle)a); } @@ -668,6 +667,11 @@ */ public void removeUpdate (DocumentEvent changes, Shape a, ViewFactory f) { + int oldNumLines = numLines; + determineNumLines(); + if (oldNumLines != numLines) + getParent().preferenceChanged(this, false, true); + updateDamage((Rectangle)a); } }
signature.asc
Description: OpenPGP digital signature