This fixes up the CompositeView to pass the Harmony testsuite.

2006-08-25  Roman Kennke  <[EMAIL PROTECTED]>

        * javax/swing/text/CompositeView.java
        (insets): Removed. Replaced by single short fields.
        (top): New field. Replaces insets.
        (bottom): New field. Replaces insets.
        (left): New field. Replaces insets.
        (right): New field. Replaces insets.
        (CompositeView): Initialize insets fields.
        (createDefaultLocation): Removed unneeded method.
        (getBottomInset): Return field directly.
        (getTopInset): Return field directly.
        (getLeftInset): Return field directly.
        (getRightInset): Return field directly.
        (getInsideAllocation): Adjusted to work on new insets fields.
        (getViewIndex): Fixed check.
        (loadChildren): Don't replace the old children.
        (replace): Make sure that there is an array to operate on.
        Only set parent to null, when it is this View.
        (setInsets): Adjusted to work with new insets fields.
        (setParagraphInsets): Fixed to pull insets directly from
        StyleConstants.

/Roman
Index: javax/swing/text/CompositeView.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/text/CompositeView.java,v
retrieving revision 1.20
diff -u -1 -2 -r1.20 CompositeView.java
--- javax/swing/text/CompositeView.java	7 Aug 2006 11:16:11 -0000	1.20
+++ javax/swing/text/CompositeView.java	25 Aug 2006 21:02:52 -0000
@@ -29,25 +29,24 @@
 modules, and to copy and distribute the resulting executable under
 terms of your choice, provided that you also meet, for each linked
 independent module, the terms and conditions of the license of that
 module.  An independent module is a module which is not derived from
 or based on this library.  If you modify this library, you may extend
 this exception to your version of the library, but you are not
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
 
 package javax.swing.text;
 
-import java.awt.Insets;
 import java.awt.Rectangle;
 import java.awt.Shape;
 
 import javax.swing.SwingConstants;
 
 /**
  * An abstract base implementation of [EMAIL PROTECTED] View} that manages child
  * <code>View</code>s.
  *
  * @author Roman Kennke ([EMAIL PROTECTED])
  */
 public abstract class CompositeView
@@ -61,60 +60,69 @@
 
   /**
    * The allocation of this <code>View</code> minus its insets. This is
    * initialized in [EMAIL PROTECTED] #getInsideAllocation} and reused and modified in
    * [EMAIL PROTECTED] #childAllocation(int, Rectangle)}.
    */
   Rectangle insideAllocation;
 
   /**
    * The insets of this <code>CompositeView</code>. This is initialized
    * in [EMAIL PROTECTED] #setInsets}.
    */
-  Insets insets;
+  private short top;
+  private short bottom;
+  private short left;
+  private short right;
 
   /**
    * Creates a new <code>CompositeView</code> for the given
    * <code>Element</code>.
    *
    * @param element the element that is rendered by this CompositeView
    */
   public CompositeView(Element element)
   {
     super(element);
     children = new View[0];
-    insets = new Insets(0, 0, 0, 0);
+    top = 0;
+    bottom = 0;
+    left = 0;
+    right = 0;
   }
 
   /**
    * Loads the child views of this <code>CompositeView</code>. This method
    * is called from [EMAIL PROTECTED] #setParent} to initialize the child views of
    * this composite view.
    *
    * @param f the view factory to use for creating new child views
    *
    * @see #setParent
    */
   protected void loadChildren(ViewFactory f)
   {
     Element el = getElement();
     int count = el.getElementCount();
     View[] newChildren = new View[count];
     for (int i = 0; i < count; ++i)
       {
         Element child = el.getElement(i);
         View view = f.create(child);
         newChildren[i] = view;
       }
-    replace(0, getViewCount(), newChildren);
+    // I'd have called replace(0, getViewCount(), newChildren) here
+    // in order to replace all existing views. However according to
+    // Harmony's tests this is not what the RI does.
+    replace(0, 0, newChildren);
   }
 
   /**
    * Sets the parent of this <code>View</code>.
    * In addition to setting the parent, this calls [EMAIL PROTECTED] #loadChildren}, if
    * this <code>View</code> does not already have its children initialized.
    *
    * @param parent the parent to set
    */
   public void setParent(View parent)
   {
     super.setParent(parent);
@@ -147,34 +155,42 @@
   /**
    * Replaces child views by some other child views. If there are no views to
    * remove (<code>length == 0</code>), the result is a simple insert, if
    * there are no children to add (<code>view == null</code>) the result
    * is a simple removal.
    *
    * @param offset the start offset from where to remove children
    * @param length the number of children to remove
    * @param views the views that replace the removed children
    */
   public void replace(int offset, int length, View[] views)
   {
+    // Make sure we have an array. The Harmony testsuite indicates that we
+    // have to do something like this.
+    if (views == null)
+      views = new View[0];
+
     // Check for null views to add.
     for (int i = 0; i < views.length; ++i)
       if (views[i] == null)
         throw new NullPointerException("Added views must not be null");
 
     int endOffset = offset + length;
 
     // First we set the parent of the removed children to null.
     for (int i = offset; i < endOffset; ++i)
-      children[i].setParent(null);
+      {
+        if (children[i].getParent() == this)
+          children[i].setParent(null);
+      }
 
     View[] newChildren = new View[children.length - length + views.length];
     System.arraycopy(children, 0, newChildren, 0, offset);
     System.arraycopy(views, 0, newChildren, offset, views.length);
     System.arraycopy(children, offset + length, newChildren,
                      offset + views.length,
                      children.length - (offset + length));
     children = newChildren;
 
     // Finally we set the parent of the added children to this.
     for (int i = 0; i < views.length; ++i)
       views[i].setParent(this);
@@ -249,45 +265,24 @@
               }
           }
         else
           {
             throw new BadLocationException("Position " + pos
                                            + " is not represented by view.", pos);
           }    
       }
     return ret;
   }
 
   /**
-   * A helper method for [EMAIL PROTECTED] #modelToView(int, Position.Bias, int,
-   * Position.Bias, Shape)}. This creates a default location when there is
-   * no child view that can take responsibility for mapping the position to
-   * view coordinates. Depending on the specified bias this will be the
-   * left or right edge of this view's allocation.
-   *
-   * @param a the allocation for this view
-   * @param bias the bias
-   *
-   * @return a default location
-   */
-  private Shape createDefaultLocation(Shape a, Position.Bias bias)
-  {
-    Rectangle alloc = a.getBounds();
-    Rectangle location = new Rectangle(alloc.x, alloc.y, 1, alloc.height);
-    if (bias == Position.Bias.Forward)
-      location.x = alloc.x + alloc.width;
-    return location;
-  }
-
-  /**
    * Maps a region in the document into the coordinate space of the View.
    *
    * @param p1 the beginning position inside the document
    * @param b1 the direction bias for the beginning position
    * @param p2 the end position inside the document
    * @param b2 the direction bias for the end position
    * @param a the area that is occupied by the view
    *
    * @return a rectangle that gives the span of the document region
    *         inside the view coordinate space
    *
    * @throws BadLocationException if <code>p1</code> or <code>p2</code> are
@@ -385,25 +380,25 @@
   /**
    * Returns the index of the child view that represents the specified
    * model location.
    *
    * @param pos the model location for which to determine the child view index
    * @param b the bias to be applied to <code>pos</code>
    *
    * @return the index of the child view that represents the specified
    *         model location
    */
   public int getViewIndex(int pos, Position.Bias b)
   {
-    if (b == Position.Bias.Backward && pos != 0)
+    if (b == Position.Bias.Backward)
       pos -= 1;
     int i = -1;
     if (pos >= getStartOffset() && pos < getEndOffset())
       i = getViewIndexAtPosition(pos);
     return i;
   }
 
   /**
    * Returns <code>true</code> if the specified point lies before the
    * given <code>Rectangle</code>, <code>false</code> otherwise.
    *
    * &quot;Before&quot; is typically defined as being to the left or above.
@@ -519,115 +514,102 @@
     // a synchronized block in order to avoid multiple threads creating
     // this instance simultanously.
     Rectangle inside;
     synchronized(this)
       {
         inside = insideAllocation;
         if (inside == null)
           {
             inside = new Rectangle();
             insideAllocation = inside;
           }
       }
-    inside.x = alloc.x + insets.left;
-    inside.y = alloc.y + insets.top;
-    inside.width = alloc.width - insets.left - insets.right;
-    inside.height = alloc.height - insets.top - insets.bottom;
+    inside.x = alloc.x + left;
+    inside.y = alloc.y + top;
+    inside.width = alloc.width - left - right;
+    inside.height = alloc.height - top - bottom;
     return inside;
   }
 
   /**
    * Sets the insets defined by attributes in <code>attributes</code>. This
    * queries the attribute keys [EMAIL PROTECTED] StyleConstants#SpaceAbove},
    * [EMAIL PROTECTED] StyleConstants#SpaceBelow}, [EMAIL PROTECTED] StyleConstants#LeftIndent} and
    * [EMAIL PROTECTED] StyleConstants#RightIndent} and calls [EMAIL PROTECTED] #setInsets} to
    * actually set the insets on this <code>CompositeView</code>.
    *
    * @param attributes the attributes from which to query the insets
    */
   protected void setParagraphInsets(AttributeSet attributes)
   {
-    Float l = (Float) attributes.getAttribute(StyleConstants.LeftIndent);
-    short left = 0;
-    if (l != null)
-      left = l.shortValue();
-    Float r = (Float) attributes.getAttribute(StyleConstants.RightIndent);
-    short right = 0;
-    if (r != null)
-      right = r.shortValue();
-    Float t = (Float) attributes.getAttribute(StyleConstants.SpaceAbove);
-    short top = 0;
-    if (t != null)
-      top = t.shortValue();
-    Float b = (Float) attributes.getAttribute(StyleConstants.SpaceBelow);
-    short bottom = 0;
-    if (b != null)
-      bottom = b.shortValue();
-    setInsets(top, left, bottom, right);
+    top = (short) StyleConstants.getSpaceAbove(attributes);
+    bottom = (short) StyleConstants.getSpaceBelow(attributes);
+    left = (short) StyleConstants.getLeftIndent(attributes);
+    right = (short) StyleConstants.getRightIndent(attributes);
   }
 
   /**
    * Sets the insets of this <code>CompositeView</code>.
    *
-   * @param top the top inset
-   * @param left the left inset
-   * @param bottom the bottom inset
-   * @param right the right inset
-   */
-  protected void setInsets(short top, short left, short bottom, short right)
-  {
-    insets.top = top;
-    insets.left = left;
-    insets.bottom = bottom;
-    insets.right = right;
+   * @param t the top inset
+   * @param l the left inset
+   * @param b the bottom inset
+   * @param r the right inset
+   */
+  protected void setInsets(short t, short l, short b, short r)
+  {
+    top = t;
+    left = l;
+    bottom = b;
+    right = r;
   }
 
   /**
    * Returns the left inset of this <code>CompositeView</code>.
    *
    * @return the left inset of this <code>CompositeView</code>
    */
   protected short getLeftInset()
   {
-    return (short) insets.left;
+    return left;
   }
 
   /**
    * Returns the right inset of this <code>CompositeView</code>.
    *
    * @return the right inset of this <code>CompositeView</code>
    */
   protected short getRightInset()
   {
-    return (short) insets.right;
+    return right;
   }
 
   /**
    * Returns the top inset of this <code>CompositeView</code>.
    *
    * @return the top inset of this <code>CompositeView</code>
    */
   protected short getTopInset()
   {
-    return (short) insets.top;
+    return top;
   }
 
   /**
    * Returns the bottom inset of this <code>CompositeView</code>.
    *
    * @return the bottom inset of this <code>CompositeView</code>
    */
   protected short getBottomInset()
   {
-    return (short) insets.bottom;
+    return bottom;
   }
 
   /**
    * Returns the next model location that is visible in north or south
    * direction.
    * This is used to determine the
    * placement of the caret when navigating around the document with
    * the arrow keys.
    *
    * @param pos the model position to start search from
    * @param b the bias for <code>pos</code>
    * @param a the allocated region for this view

Reply via email to