This makes my recently added testcases for the above said classes PASS,
as well as one of the regressions. Basically this adds a little
robustness to the getStart/EndOffset() methods in Branch/LeafElement for
certain strange situations.

2006-02-28  Roman Kennke  <[EMAIL PROTECTED]>

        * javax/swing/text/BranchElement.java
        (startOffset): New field.
        (endOffset): New field.
        (BranchElement): Initialize new fields.
        (getEndOffset): Rewritten to possibly return cached values
        if element has no children.
        (getStartOffset): Rewritten to possibly return cached values
        if element has no children.
        * javax/swing/text/LeafElement.java
        (startDelta): New field.
        (endDelta): New field.
        (LeafElement): Handle possible delta of start/endOffset when
        these parameters lie outside the document range.
        (getStartOffset): Handle possible startDelta.
        (getEndOffset): Handle possible startDelta.

/Roman
Index: javax/swing/text/AbstractDocument.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/text/AbstractDocument.java,v
retrieving revision 1.51
diff -u -r1.51 AbstractDocument.java
--- javax/swing/text/AbstractDocument.java	21 Feb 2006 13:56:15 -0000	1.51
+++ javax/swing/text/AbstractDocument.java	28 Feb 2006 16:15:51 -0000
@@ -1586,6 +1586,18 @@
     private Element[] children = new Element[0];
 
     /**
+     * The cached startOffset value. This is used in the case when a
+     * BranchElement (temporarily) has no child elements.
+     */
+    private int startOffset;
+
+    /**
+     * The cached endOffset value. This is used in the case when a
+     * BranchElement (temporarily) has no child elements.
+     */
+    private int endOffset;
+
+    /**
      * Creates a new <code>BranchElement</code> with the specified
      * parent and attributes.
      *
@@ -1596,6 +1608,8 @@
     public BranchElement(Element parent, AttributeSet attributes)
     {
       super(parent, attributes);
+      startOffset = -1;
+      endOffset = -1;
     }
 
     /**
@@ -1668,7 +1682,7 @@
       // return 0
       if (offset < getStartOffset())
         return 0;
-      
+
       // XXX: There is surely a better algorithm
       // as beginning from first element each time.
       for (int index = 0; index < children.length - 1; ++index)
@@ -1708,12 +1722,15 @@
      */
     public int getEndOffset()
     {
-      int end = 0;
-      if (getElementCount() == 0)
-        end = getLength(); // FIXME: That ain't correct, fix it.
+      if (children.length == 0)
+        {
+          if (endOffset == -1)
+            throw new NullPointerException("BranchElement has no children.");
+        }
       else
-        end = children[children.length - 1].getEndOffset();
-      return end;
+        endOffset = children[children.length - 1].getEndOffset();
+
+      return endOffset;
     }
 
     /**
@@ -1734,16 +1751,20 @@
      *
      * @return the start offset of this element inside the document model
      *
-     * @throws NullPointerException if this branch element has no children
+     * @throws NullPointerException if this branch element has no children and
+     *         no startOffset value has been cached
      */
     public int getStartOffset()
     {
-      int start = 0;
-      if (getElementCount() == 0)
-        start = 0; // FIXME: That ain't correct, fix it.
+      if (children.length == 0)
+        {
+          if (startOffset == -1)
+            throw new NullPointerException("BranchElement has no children.");
+        }
       else
-        start = children[0].getStartOffset();
-      return start;
+        startOffset = children[0].getStartOffset();
+
+      return startOffset;
     }
 
     /**
@@ -2041,13 +2062,29 @@
     /** The serialization UID (compatible with JDK1.5). */
     private static final long serialVersionUID = -8906306331347768017L;
 
-    /** Manages the start offset of this element. */
-    Position startPos;
+    /**
+     * Manages the start offset of this element.
+     */
+    private Position startPos;
 
-    /** Manages the end offset of this element. */
-    Position endPos;
+    /**
+     * Manages the end offset of this element.
+     */
+    private Position endPos;
 
     /**
+     * This gets possible added to the startOffset when a startOffset
+     * outside the document range is requested.
+     */
+    private int startDelta;
+
+    /**
+     * This gets possible added to the endOffset when a endOffset
+     * outside the document range is requested.
+     */
+    private int endDelta;
+    
+    /**
      * Creates a new <code>LeafElement</code>.
      *
      * @param parent the parent of this <code>LeafElement</code>
@@ -2059,20 +2096,18 @@
                        int end)
     {
       super(parent, attributes);
-	{
-	  try
+      startDelta = 0;
+      if (start > getLength())
+        startDelta = start - getLength();
+      endDelta = 0;
+      if (end > getLength())
+        endDelta = end - getLength();
+
+      try
 	    {
-	      if (parent != null)
-		{
-		  startPos = parent.getDocument().createPosition(start);
-		  endPos = parent.getDocument().createPosition(end);
-		}
-	      else
-		{
-		  startPos = createPosition(start);
-		  endPos = createPosition(end);
+		  startPos = createPosition(start - startDelta);
+		  endPos = createPosition(end - endDelta);
 		}
-	    }
 	  catch (BadLocationException ex)
 	    {
 	      AssertionError as;
@@ -2083,7 +2118,6 @@
 	      as.initCause(ex);
 	      throw as;
 	    }
-	}
     }
 
     /**
@@ -2155,7 +2189,7 @@
      */
     public int getEndOffset()
     {
-      return endPos.getOffset();
+      return endPos.getOffset() + endDelta;
     }
 
     /**
@@ -2181,7 +2215,7 @@
      */
     public int getStartOffset()
     {
-      return startPos.getOffset();
+      return startPos.getOffset() + startDelta;
     }
 
     /**

Reply via email to