Hi,
this patch fixes the broken up/down movement in JTextArea /w lineWrap=true[0]
(which use a WrappedPlainView) for real!.

The faulty behavior was spread along many classes in javax.swing.text but now
its fixed.

The ChangeLog:

2006-04-01  Robert Schuster  <[EMAIL PROTECTED]>

        * javax/swing/text/CompositeView.java:
        (modelToView): Throw BadLocationException when no child
        view can be found, restructed to throw exception as early
        as possible.
        (viewToModel): Use mutable allocation as argument for viewToModel
        call on child view.
        * javax/swing/text/BoxView.java:
        (getViewAtPoint): Call setBounds() r before method returns with
        suitable child view.
        * javax/swing/text/Utilities.java:
        (getPositionBelow): Added try-catch-block around modelToView call,
        added method return when BadLocationException was thrown.
        * javax/swing/text/WrappedPlainView.java:
        (WrappedLine.viewToModel): Changed '<' to '<=' in if-expression,
        added note about meaning of rect.x and rect.width, removed unneeded
        checks, added code to not return the last possible document offset.

cya
Robert

[0] - http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26843

Index: javax/swing/text/CompositeView.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/text/CompositeView.java,v
retrieving revision 1.15
diff -u -r1.15 CompositeView.java
--- javax/swing/text/CompositeView.java	1 Mar 2006 20:39:49 -0000	1.15
+++ javax/swing/text/CompositeView.java	1 Apr 2006 14:52:44 -0000
@@ -218,21 +218,24 @@
     throws BadLocationException
   {
     int childIndex = getViewIndex(pos, bias);
+    if (childIndex == -1)
+      throw new BadLocationException("Position " + pos + " is not represented by view.", pos);
+      
     Shape ret = null;
-    if (childIndex != -1)
-      {
-        View child = getView(childIndex);
-        Shape childAlloc = getChildAllocation(childIndex, a);
-        if (childAlloc == null)
-          ret = createDefaultLocation(a, bias);
-        Shape result = child.modelToView(pos, childAlloc, bias);
-        if (result != null)
-          ret = result;
-        else
-          ret =  createDefaultLocation(a, bias);
-      }
-    else
+
+    View child = getView(childIndex);
+    Shape childAlloc = getChildAllocation(childIndex, a);
+    
+    if (childAlloc == null)
       ret = createDefaultLocation(a, bias);
+    
+    Shape result = child.modelToView(pos, childAlloc, bias);
+
+    if (result != null)
+      ret = result;
+    else
+      ret =  createDefaultLocation(a, bias);
+
     return ret;
   }
 
@@ -301,7 +304,7 @@
       {
         Rectangle r = getInsideAllocation(a);
         View view = getViewAtPoint((int) x, (int) y, r);
-        return view.viewToModel(x, y, a, b);
+        return view.viewToModel(x, y, r, b);
       }
     return 0;
   }
Index: javax/swing/text/BoxView.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/text/BoxView.java,v
retrieving revision 1.17
diff -u -r1.17 BoxView.java
--- javax/swing/text/BoxView.java	1 Apr 2006 12:52:54 -0000	1.17
+++ javax/swing/text/BoxView.java	1 Apr 2006 14:52:44 -0000
@@ -595,6 +595,8 @@
         childAllocation(i, copy);
         if (copy.contains(x, y))
           {
+            // Modify r on success.
+            r.setBounds(copy);
             result = getView(i);
             break;
           }
Index: javax/swing/text/Utilities.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/text/Utilities.java,v
retrieving revision 1.26
diff -u -r1.26 Utilities.java
--- javax/swing/text/Utilities.java	17 Mar 2006 15:29:33 -0000	1.26
+++ javax/swing/text/Utilities.java	1 Apr 2006 14:52:44 -0000
@@ -621,8 +621,22 @@
     if(offs == -1)
       return -1;
 
-    // Effectively calculates the y value of the previous line.
-    Point pt = c.modelToView(offs+1).getLocation();
+    Point pt = null;
+    
+    // Note: Some views represent the position after the last
+    // typed character others do not. Converting offset 3 in "a\nb"
+    // in a PlainView will return a valid rectangle while in a
+    // WrappedPlainView this will throw a BadLocationException.
+    // This behavior has been observed in the RI.
+    try
+      {
+        // Effectively calculates the y value of the next line.
+        pt = c.modelToView(offs+1).getLocation();
+      }
+    catch(BadLocationException ble)
+      {
+        return offset;
+      }
     
     pt.x = x;
     
Index: javax/swing/text/WrappedPlainView.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/text/WrappedPlainView.java,v
retrieving revision 1.12
diff -u -r1.12 WrappedPlainView.java
--- javax/swing/text/WrappedPlainView.java	1 Apr 2006 12:52:54 -0000	1.12
+++ javax/swing/text/WrappedPlainView.java	1 Apr 2006 14:52:44 -0000
@@ -582,20 +582,18 @@
         return currLineStart;
       if (y > rect.y + rect.height)
         return end - 1;
+      
+      // 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
+      // is most of the time identical to the component's width.
 
       while (true)
         {
           int currLineEnd = calculateBreakPosition(currLineStart, end);
           // If we're at the right y-position that means we're on the right
           // logical line and we should look for the character
-          if (y >= rect.y && y <= rect.y + lineHeight)
+          if (y >= rect.y && y < rect.y + lineHeight)
             {
-              // Check if the x position is to the left or right of the text
-              if (x < rect.x)
-                return currLineStart;
-              if (x > rect.x + rect.width)
-                return currLineEnd - 1;
-
               try
                 {
                   getDocument().getText(currLineStart, end - currLineStart, s);
@@ -605,10 +603,15 @@
                   // Shouldn't happen
                 }
               
-              return Utilities.getTabbedTextOffset(s, metrics, rect.x,
+              int mark = 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;

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to