summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLillian Angel <langel@redhat.com>2006-01-26 21:20:28 +0000
committerLillian Angel <langel@redhat.com>2006-01-26 21:20:28 +0000
commit2d419c18a997a62aea8439069681adc31229f808 (patch)
treed09d516e93f4bb61e1508a7230cd998dd13c5ff8
parent8078e6fd383047eec75292dd6c981b29e8741837 (diff)
downloadclasspath-2d419c18a997a62aea8439069681adc31229f808.tar.gz
2006-01-26 Lillian Angel <langel@redhat.com>
* javax/swing/text/DefaultStyledDocument.java (ElementBuffer): Added fields. (remove): Initialized pos. (change): Likewise. (insert): Likewise. (insertUpdate): Incremented pos. Fixed check, createFracture should be called on first tag if it is not ContentType. (insertFirstContentTag): Reworked to use proper offsets and set offset accordingly. This might need more work in the future. (insertContentTag): Likewise. Fixed to use pos, instead of offset. (createFracture): Fixed to recreate other leaves. Still needs more work. (insertFracture): Reimplemented. (recreateAfterFracture): New method. (getParagraphElement): Reimplemented, more efficent.
-rw-r--r--ChangeLog21
-rw-r--r--javax/swing/text/DefaultStyledDocument.java1216
2 files changed, 655 insertions, 582 deletions
diff --git a/ChangeLog b/ChangeLog
index 7f4163d1c..81ae00333 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,10 +1,29 @@
+2006-01-26 Lillian Angel <langel@redhat.com>
+
+ * javax/swing/text/DefaultStyledDocument.java
+ (ElementBuffer): Added fields.
+ (remove): Initialized pos.
+ (change): Likewise.
+ (insert): Likewise.
+ (insertUpdate): Incremented pos. Fixed check, createFracture should
+ be called on first tag if it is not ContentType.
+ (insertFirstContentTag): Reworked to use proper offsets and
+ set offset accordingly. This might need more work in the future.
+ (insertContentTag): Likewise. Fixed to use pos, instead of
+ offset.
+ (createFracture): Fixed to recreate other leaves. Still needs
+ more work.
+ (insertFracture): Reimplemented.
+ (recreateAfterFracture): New method.
+ (getParagraphElement): Reimplemented, more efficent.
+
2006-01-26 Christian Thalinger <twisti@complang.tuwien.ac.at>
* native/jni/java-lang/java_lang_VMDouble.c (doubleToLongBits)
(doubleToRawLongBits, longBitsToDouble): Swap the byte
ordering for little-endian arms without VFP.
-2006-01-27 Raif S. Naffah <raif@swiftdsl.com.au>
+2006-01-26 Raif S. Naffah <raif@swiftdsl.com.au>
PR classpath/25981
* gnu/javax/crypto/jce/GnuCrypto.java (run): Added KeyGenerator entries.
diff --git a/javax/swing/text/DefaultStyledDocument.java b/javax/swing/text/DefaultStyledDocument.java
index 873a87a35..795941654 100644
--- a/javax/swing/text/DefaultStyledDocument.java
+++ b/javax/swing/text/DefaultStyledDocument.java
@@ -53,28 +53,25 @@ import javax.swing.undo.AbstractUndoableEdit;
import javax.swing.undo.UndoableEdit;
/**
- * The default implementation of {@link StyledDocument}.
- *
- * The document is modeled as an {@link Element} tree, which has
- * a {@link SectionElement} as single root, which has one or more
- * {@link AbstractDocument.BranchElement}s as paragraph nodes
- * and each paragraph node having one or more
+ * The default implementation of {@link StyledDocument}. The document is
+ * modeled as an {@link Element} tree, which has a {@link SectionElement} as
+ * single root, which has one or more {@link AbstractDocument.BranchElement}s
+ * as paragraph nodes and each paragraph node having one or more
* {@link AbstractDocument.LeafElement}s as content nodes.
- *
+ *
* @author Michael Koch (konqueror@gmx.de)
* @author Roman Kennke (roman@kennke.org)
*/
-public class DefaultStyledDocument extends AbstractDocument
- implements StyledDocument
+public class DefaultStyledDocument extends AbstractDocument implements
+ StyledDocument
{
-
+
/**
* An {@link UndoableEdit} that can undo attribute changes to an element.
- *
+ *
* @author Roman Kennke (kennke@aicas.com)
*/
- public static class AttributeUndoableEdit
- extends AbstractUndoableEdit
+ public static class AttributeUndoableEdit extends AbstractUndoableEdit
{
/**
* A copy of the old attributes.
@@ -99,11 +96,13 @@ public class DefaultStyledDocument extends AbstractDocument
/**
* Creates a new <code>AttributeUndoableEdit</code>.
- *
- * @param el the element that changes attributes
- * @param newAtts the new attributes
- * @param replacing if the new attributes replace the old or only append to
- * them
+ *
+ * @param el
+ * the element that changes attributes
+ * @param newAtts
+ * the new attributes
+ * @param replacing
+ * if the new attributes replace the old or only append to them
*/
public AttributeUndoableEdit(Element el, AttributeSet newAtts,
boolean replacing)
@@ -150,21 +149,19 @@ public class DefaultStyledDocument extends AbstractDocument
}
/**
- * Carries specification information for new {@link Element}s that should
- * be created in {@link ElementBuffer}. This allows the parsing process
- * to be decoupled from the <code>Element</code> creation process.
+ * Carries specification information for new {@link Element}s that should be
+ * created in {@link ElementBuffer}. This allows the parsing process to be
+ * decoupled from the <code>Element</code> creation process.
*/
public static class ElementSpec
{
/**
- * This indicates a start tag. This is a possible value for
- * {@link #getType}.
+ * This indicates a start tag. This is a possible value for {@link #getType}.
*/
public static final short StartTagType = 1;
/**
- * This indicates an end tag. This is a possible value for
- * {@link #getType}.
+ * This indicates an end tag. This is a possible value for {@link #getType}.
*/
public static final short EndTagType = 2;
@@ -176,22 +173,19 @@ public class DefaultStyledDocument extends AbstractDocument
/**
* This indicates that the data associated with this spec should be joined
- * with what precedes it. This is a possible value for
- * {@link #getDirection}.
+ * with what precedes it. This is a possible value for {@link #getDirection}.
*/
public static final short JoinPreviousDirection = 4;
/**
* This indicates that the data associated with this spec should be joined
- * with what follows it. This is a possible value for
- * {@link #getDirection}.
+ * with what follows it. This is a possible value for {@link #getDirection}.
*/
public static final short JoinNextDirection = 5;
/**
- * This indicates that the data associated with this spec should be used
- * to create a new element. This is a possible value for
- * {@link #getDirection}.
+ * This indicates that the data associated with this spec should be used to
+ * create a new element. This is a possible value for {@link #getDirection}.
*/
public static final short OriginateDirection = 6;
@@ -235,9 +229,11 @@ public class DefaultStyledDocument extends AbstractDocument
/**
* Creates a new <code>ElementSpec</code> with no content, length or
* offset. This is most useful for start and end tags.
- *
- * @param a the attributes for the element to be created
- * @param type the type of the tag
+ *
+ * @param a
+ * the attributes for the element to be created
+ * @param type
+ * the type of the tag
*/
public ElementSpec(AttributeSet a, short type)
{
@@ -248,27 +244,34 @@ public class DefaultStyledDocument extends AbstractDocument
* Creates a new <code>ElementSpec</code> that specifies the length but
* not the offset of an element. Such <code>ElementSpec</code>s are
* processed sequentially from a known starting point.
- *
- * @param a the attributes for the element to be created
- * @param type the type of the tag
- * @param len the length of the element
+ *
+ * @param a
+ * the attributes for the element to be created
+ * @param type
+ * the type of the tag
+ * @param len
+ * the length of the element
*/
public ElementSpec(AttributeSet a, short type, int len)
{
this(a, type, null, 0, len);
}
-
+
/**
* Creates a new <code>ElementSpec</code> with document content.
- *
- * @param a the attributes for the element to be created
- * @param type the type of the tag
- * @param txt the actual content
- * @param offs the offset into the <code>txt</code> array
- * @param len the length of the element
+ *
+ * @param a
+ * the attributes for the element to be created
+ * @param type
+ * the type of the tag
+ * @param txt
+ * the actual content
+ * @param offs
+ * the offset into the <code>txt</code> array
+ * @param len
+ * the length of the element
*/
- public ElementSpec(AttributeSet a, short type, char[] txt, int offs,
- int len)
+ public ElementSpec(AttributeSet a, short type, char[] txt, int offs, int len)
{
attributes = a;
this.type = type;
@@ -280,8 +283,9 @@ public class DefaultStyledDocument extends AbstractDocument
/**
* Sets the type of the element.
- *
- * @param type the type of the element to be set
+ *
+ * @param type
+ * the type of the element to be set
*/
public void setType(short type)
{
@@ -290,7 +294,7 @@ public class DefaultStyledDocument extends AbstractDocument
/**
* Returns the type of the element.
- *
+ *
* @return the type of the element
*/
public short getType()
@@ -300,8 +304,9 @@ public class DefaultStyledDocument extends AbstractDocument
/**
* Sets the direction of the element.
- *
- * @param dir the direction of the element to be set
+ *
+ * @param dir
+ * the direction of the element to be set
*/
public void setDirection(short dir)
{
@@ -310,7 +315,7 @@ public class DefaultStyledDocument extends AbstractDocument
/**
* Returns the direction of the element.
- *
+ *
* @return the direction of the element
*/
public short getDirection()
@@ -320,7 +325,7 @@ public class DefaultStyledDocument extends AbstractDocument
/**
* Returns the attributes of the element.
- *
+ *
* @return the attributes of the element
*/
public AttributeSet getAttributes()
@@ -330,7 +335,7 @@ public class DefaultStyledDocument extends AbstractDocument
/**
* Returns the actual content of the element.
- *
+ *
* @return the actual content of the element
*/
public char[] getArray()
@@ -340,7 +345,7 @@ public class DefaultStyledDocument extends AbstractDocument
/**
* Returns the offset of the content.
- *
+ *
* @return the offset of the content
*/
public int getOffset()
@@ -350,7 +355,7 @@ public class DefaultStyledDocument extends AbstractDocument
/**
* Returns the length of the content.
- *
+ *
* @return the length of the content
*/
public int getLength()
@@ -362,7 +367,7 @@ public class DefaultStyledDocument extends AbstractDocument
* Returns a String representation of this <code>ElementSpec</code>
* describing the type, direction and length of this
* <code>ElementSpec</code>.
- *
+ *
* @return a String representation of this <code>ElementSpec</code>
*/
public String toString()
@@ -410,8 +415,8 @@ public class DefaultStyledDocument extends AbstractDocument
return b.toString();
}
- }
-
+ }
+
/**
* Performs all <em>structural</code> changes to the <code>Element</code>
* hierarchy. This class was implemented with much help from the document:
@@ -433,10 +438,13 @@ public class DefaultStyledDocument extends AbstractDocument
/** Holds the length of structural changes. */
private int length;
-
- /** Holds the element that was created by insertFirstContentTag. */
- private Element firstCreated;
-
+
+ /** Holds the position of the change. */
+ private int pos;
+
+ /** Holds the element that was last fractured. */
+ private Element lastFractured;
+
/**
* The current position in the element tree. This is used for bulk inserts
* using ElementSpecs.
@@ -488,6 +496,7 @@ public class DefaultStyledDocument extends AbstractDocument
return;
offset = offs;
length = len;
+ pos = offset;
documentEvent = ev;
removeUpdate();
}
@@ -625,6 +634,7 @@ public class DefaultStyledDocument extends AbstractDocument
if (length == 0)
return;
this.offset = offset;
+ this.pos = offset;
this.length = length;
documentEvent = ev;
changeUpdate();
@@ -651,6 +661,7 @@ public class DefaultStyledDocument extends AbstractDocument
if (length == 0)
return;
this.offset = offset;
+ this.pos = offset;
this.endOffset = offset + length;
this.length = length;
documentEvent = ev;
@@ -680,7 +691,7 @@ public class DefaultStyledDocument extends AbstractDocument
addEdit(e, curr.index, removed, added);
}
}
-
+
/**
* Inserts new content
*
@@ -698,9 +709,13 @@ public class DefaultStyledDocument extends AbstractDocument
// no extra LeafElements are erroneously inserted.
i = 1;
insertFirstContentTag(data);
+ pos += data[0].length;
+ }
+ else
+ {
+ i = 0;
+ createFracture(data);
}
- else if (type == ElementSpec.StartTagType)
- createFracture(data);
// Handle each ElementSpec individually.
for (; i < data.length; i++)
@@ -722,15 +737,13 @@ public class DefaultStyledDocument extends AbstractDocument
int index = paragraph.getElementIndex(offset);
elementStack.push(paragraph.getElement(index));
break;
- case ElementSpec.OriginateDirection:
+ default:
// Create a new paragraph and push it onto the stack.
Element current = (Element) elementStack.peek();
Element newParagraph = insertParagraph((BranchElement) current,
offset);
elementStack.push(newParagraph);
break;
- default:
- break;
}
break;
case ElementSpec.EndTagType:
@@ -742,11 +755,72 @@ public class DefaultStyledDocument extends AbstractDocument
}
}
}
-
+
+ /**
+ * Inserts a new paragraph.
+ *
+ * @param par - the parent
+ * @param offset - the offset
+ * @return the new paragraph
+ */
+ private Element insertParagraph(BranchElement par, int offset)
+ {
+ Element current = par.getElement(par.getElementIndex(offset));
+ Element[] res = split(current, offset, 0);
+ int index = par.getElementIndex(offset);
+ Element ret;
+ if (res[1] != null)
+ {
+ Element[] removed;
+ Element[] added;
+ if (res[0] == null)
+ {
+ removed = new Element[0];
+ if (res[1] instanceof BranchElement)
+ {
+ added = new Element[] { res[1] };
+ ret = res[1];
+ }
+ else
+ {
+ ret = createBranchElement(par, null);
+ added = new Element[] { ret, res[1] };
+ }
+ index++;
+ }
+ else
+ {
+ removed = new Element[] { current };
+ if (res[1] instanceof BranchElement)
+ {
+ ret = res[1];
+ added = new Element[] { res[0], res[1] };
+ }
+ else
+ {
+ ret = createBranchElement(par, null);
+ added = new Element[] { res[0], ret, res[1] };
+ }
+ }
+ Edit e = getEditForParagraphAndIndex(par, index);
+ e.addAddedElements(added);
+ e.addRemovedElements(removed);
+ }
+ else
+ {
+ ret = createBranchElement(par, null);
+ Element[] added = new Element[] { ret };
+ Edit e = getEditForParagraphAndIndex(par, index);
+ e.addAddedElements(added);
+ }
+ return ret;
+ }
+
/**
* Inserts the first tag into the document.
*
- * @param data - the data to be inserted.
+ * @param data -
+ * the data to be inserted.
*/
private void insertFirstContentTag(ElementSpec[] data)
{
@@ -755,239 +829,204 @@ public class DefaultStyledDocument extends AbstractDocument
int index = paragraph.getElementIndex(offset);
Element current = paragraph.getElement(index);
int newEndOffset = offset + first.length;
- Edit edit = getEditForParagraphAndIndex(paragraph, index);
boolean onlyContent = data.length == 1;
-
+ Edit edit = getEditForParagraphAndIndex(paragraph, index);
+
switch (first.getDirection())
{
case ElementSpec.JoinPreviousDirection:
- int end = newEndOffset;
- if (onlyContent)
- end = current.getEndOffset();
-
- if (current.getEndOffset() != end)
+ if (current.getEndOffset() != newEndOffset && !onlyContent)
{
Element newEl1 = createLeafElement(paragraph,
current.getAttributes(),
current.getStartOffset(),
- end);
- firstCreated = newEl1;
- edit.addRemovedElement(current);
+ newEndOffset);
+
edit.addAddedElement(newEl1);
+ edit.addRemovedElement(current);
+
+ if (current.getEndOffset() != endOffset)
+ {
+ // recreate all other leaves
+ Element newEl2 = createLeafElement(paragraph,
+ current.getAttributes(),
+ newEndOffset,
+ current.getEndOffset());
+ edit.addAddedElement(newEl2);
+ }
}
+ offset = newEndOffset;
break;
case ElementSpec.JoinNextDirection:
if (offset != 0)
{
- Element next = paragraph.getElement(index + 1);
- Element[] removed = new Element[] { current, next };
Element newEl1 = createLeafElement(paragraph,
current.getAttributes(),
current.getStartOffset(),
offset);
- firstCreated = newEl1;
- Element[] added = new Element[2];
- added[0] = newEl1;
-
- end = newEndOffset;
+ edit.addAddedElement(newEl1);
+
+ Element next = paragraph.getElement(index + 1);
+
if (onlyContent)
- end = next.getEndOffset();
-
- added[1] = createLeafElement(paragraph, next.getAttributes(),
- offset, end);
- edit.addRemovedElements(removed);
- edit.addAddedElements(added);
+ newEl1 = createLeafElement(paragraph, next.getAttributes(),
+ offset, next.getEndOffset());
+ else
+ newEl1 = createLeafElement(paragraph, next.getAttributes(),
+ offset, newEndOffset);
+ edit.addAddedElement(newEl1);
+ edit.addRemovedElement(current);
+ edit.addRemovedElement(next);
}
break;
- case ElementSpec.OriginateDirection:
+ default:
if (current.getStartOffset() != offset)
{
- Element newEl1 = createLeafElement(paragraph,
- current.getAttributes(),
- current.getStartOffset(),
- offset);
- firstCreated = newEl1;
- edit.addAddedElement(newEl1);
+ Element newEl = createLeafElement(paragraph,
+ current.getAttributes(),
+ current.getStartOffset(),
+ offset);
+ edit.addAddedElement(newEl);
}
- Element newEl2 = createLeafElement(paragraph, first.getAttributes(),
- offset, newEndOffset);
- edit.addAddedElement(newEl2);
edit.addRemovedElement(current);
-
- if (current.getEndOffset() != newEndOffset && onlyContent)
- {
- // This means all the leaves that were there previously need
- // to be recreated after all the new Elements are inserted.
- Element newCurrent = createLeafElement(paragraph,
- current.getAttributes(),
- newEndOffset,
- current.getEndOffset());
- edit.addAddedElement(newCurrent);
- }
- else if (!onlyContent)
+ Element newEl1 = createLeafElement(paragraph, first.getAttributes(),
+ offset, newEndOffset);
+ edit.addAddedElement(newEl1);
+ if (current.getEndOffset() != endOffset)
{
- int size = paragraph.getElementCount();
- for (int i = index + 1; i < size; i++)
- edit.addRemovedElement(paragraph.getElement(i));
+ // recreate all other leaves
+ Element newEl2 = createLeafElement(paragraph,
+ current.getAttributes(),
+ newEndOffset,
+ current.getEndOffset());
+ edit.addAddedElement(newEl2);
}
- break;
- default:
+ else
+ offset = newEndOffset;
break;
}
- offset = newEndOffset;
}
/**
* Inserts a content element into the document structure.
*
- * @param tag the element spec
+ * @param tag -
+ * the element spec
*/
private void insertContentTag(ElementSpec tag)
{
int len = tag.getLength();
int dir = tag.getDirection();
AttributeSet tagAtts = tag.getAttributes();
+ BranchElement paragraph = (BranchElement) elementStack.peek();
+ int index = paragraph.getElementIndex(pos);
+ Element target = paragraph.getElement(index);
+ Edit edit = getEditForParagraphAndIndex(paragraph, index);
if (dir == ElementSpec.JoinNextDirection)
{
- BranchElement paragraph = (BranchElement) elementStack.peek();
- int index = paragraph.getElementIndex(offset);
- Element target = paragraph.getElement(index);
- Edit edit = getEditForParagraphAndIndex(paragraph, index);
-
- if (paragraph.getStartOffset() > offset)
+ if (paragraph.getStartOffset() > pos)
{
Element first = paragraph.getElement(0);
Element newEl = createLeafElement(paragraph,
- first.getAttributes(), offset,
+ first.getAttributes(), pos,
first.getEndOffset());
edit.addAddedElement(newEl);
edit.addRemovedElement(first);
}
- else if (paragraph.getElementCount() > (index + 1))
+ else if (paragraph.getElementCount() > (index + 1)
+ && (pos == target.getStartOffset() && !target.equals(lastFractured)))
{
Element next = paragraph.getElement(index + 1);
- if (offset == target.getStartOffset())
{
Element newEl = createLeafElement(paragraph,
- next.getAttributes(),
- offset, next.getEndOffset());
+ next.getAttributes(), pos,
+ next.getEndOffset());
edit.addAddedElement(newEl);
edit.addRemovedElement(next);
edit.addRemovedElement(target);
}
- else
- {
- Element newEl1 = createLeafElement(paragraph,
- target.getAttributes(),
- target.getStartOffset(),
- offset);
- Element newEl2 = createLeafElement(paragraph,
- next.getAttributes(),
- offset,
- next.getEndOffset());
- edit.addRemovedElement(target);
- edit.addRemovedElement(next);
- edit.addAddedElement(newEl1);
- edit.addAddedElement(newEl2);
- }
- }
- }
- else if (dir == ElementSpec.OriginateDirection)
- {
- BranchElement paragraph = (BranchElement) elementStack.peek();
- int index = paragraph.getElementIndex(offset);
- Element current = paragraph.getElement(index);
-
- Element[] added;
- Element[] removed = new Element[] { current };
- Element[] splitRes = split(current, offset, len);
-
- if (splitRes[0] == null)
- {
- added = new Element[2];
- added[0] = new LeafElement(paragraph, tagAtts, offset,
- endOffset);
- added[1] = splitRes[1];
- removed = new Element[0];
- index++;
- }
- else if (current.getStartOffset() == offset && current.getEndOffset() == endOffset)
- {
- added = new Element[1];
- added[0] = new LeafElement(paragraph, tagAtts, offset,
- endOffset);
- }
- else if (current.getStartOffset() == offset)
- {
- // This is if the new insertion happens immediately before
- // the <code>current</code> Element. In this case there are 2
- // resulting Elements.
- added = new Element[2];
- added[0] = new LeafElement(paragraph, tagAtts, offset,
- endOffset);
- added[1] = splitRes[1];
- }
- else if (current.getEndOffset() == endOffset)
- {
- // This is if the new insertion happens right at the end of
- // the <code>current</code> Element. In this case there are
- // 2 resulting Elements.
- added = new Element[2];
- added[0] = splitRes[0];
- added[1] = new LeafElement(paragraph, tagAtts, offset,
- endOffset);
- }
- else
- {
- // This is if the new insertion is in the middle of the
- // <code>current</code> Element. In this case
- // there will be 3 resulting Elements.
- added = new Element[3];
- added[0] = splitRes[0];
- added[1] = new LeafElement(paragraph, tagAtts, offset,
- endOffset);
- added[2] = splitRes[1];
}
- Edit edit = getEditForParagraphAndIndex(paragraph, index);
- edit.addRemovedElements(removed);
- edit.addAddedElements(added);
}
- offset += len;
+ pos += len;
}
-
+
/**
* This method fractures the child at offset.
- * @param data the ElementSpecs used for the entire insertion
+ *
+ * @param data
+ * the ElementSpecs used for the entire insertion
*/
private void createFracture(ElementSpec[] data)
{
- BranchElement paragraph = (BranchElement)elementStack.peek();
+ BranchElement paragraph = (BranchElement) elementStack.peek();
int index = paragraph.getElementIndex(offset);
Element child = paragraph.getElement(index);
Edit edit = getEditForParagraphAndIndex(paragraph, index);
+ AttributeSet atts = data[0].getAttributes();
+
if (offset != 0)
{
- Element newEl1 = createLeafElement(paragraph, child.getAttributes(), child.getStartOffset(), offset);
+ // FIXME: sometimes creating too many els
+ Element newEl1 = createLeafElement(paragraph, atts,
+ child.getStartOffset(), offset);
edit.addAddedElement(newEl1);
+
+ // add rest of leaf to next branch, if it exists.
+ BranchElement parent = (BranchElement) paragraph.getParentElement();
+ int parIndex = parent.getElementIndex(offset);
+ BranchElement next = (BranchElement) parent.getElement(parIndex + 1);
+ if (next == null)
+ {
+ BranchElement newB = (BranchElement) createBranchElement(parent,
+ atts);
+ Element newEl2 = createLeafElement(newB, atts, offset,
+ child.getEndOffset());
+ newB.replace(0, 0, new Element[] { newEl2 });
+ Edit e = getEditForParagraphAndIndex(newB, 0);
+ e.addAddedElement(newB);
+ elementStack.push(newB);
+ }
+ else
+ {
+ // FIXME: need to tag those elements to ignore, those created by the fracture
+ // don't join with those elements.
+ int end = child.getEndOffset();
+
+ Edit e = getEditForParagraphAndIndex(next, parIndex);
+
+ // check if can join with next leaf
+ Element nextLeaf = next.getElement(0);
+ if (nextLeaf != null && nextLeaf.isLeaf()
+ && nextLeaf.getAttributes().isEqual(atts))
+ {
+ end = nextLeaf.getEndOffset();
+ e.addRemovedElement(nextLeaf);
+ }
+
+ Element newEl2 = createLeafElement(next, atts, offset, end);
+ e.addAddedElement(newEl2);
+ }
}
edit.addRemovedElement(child);
}
-
+
/**
- * Splits an element if <code>offset</code> is not already at its boundary.
- *
- * @param el the Element to possibly split
- * @param offset the offset at which to possibly split
- * @param space the amount of space to create between the splitted parts
- *
- * @return An array of elements which represent the split result. This
- * array has two elements, the two parts of the split. The first
- * element might be null, which means that the element which should
- * be splitted can remain in place. The second element might also
- * be null, which means that the offset is already at an element
+ * Splits an element if <code>offset</code> is not already at its
+ * boundary.
+ *
+ * @param el
+ * the Element to possibly split
+ * @param offset
+ * the offset at which to possibly split
+ * @param space
+ * the amount of space to create between the splitted parts
+ * @return An array of elements which represent the split result. This array
+ * has two elements, the two parts of the split. The first element
+ * might be null, which means that the element which should be
+ * splitted can remain in place. The second element might also be
+ * null, which means that the offset is already at an element
* boundary and the element doesn't need to be splitted.
- *
*/
private Element[] split(Element el, int offset, int space)
{
@@ -1016,14 +1055,14 @@ public class DefaultStyledDocument extends AbstractDocument
{
removed = new Element[count - index - 1];
newAdded = new Element[count - index - 1];
- added = new Element[]{};
+ added = new Element[] {};
}
// This is the case when we may not keep the first element.
else
{
removed = new Element[count - index];
newAdded = new Element[count - index];
- added = new Element[]{result[0]};
+ added = new Element[] { result[0] };
}
newAdded[0] = result[1];
for (int i = index; i < count; i++)
@@ -1035,16 +1074,15 @@ public class DefaultStyledDocument extends AbstractDocument
newAdded[ind] = el2;
}
- Edit edit = getEditForParagraphAndIndex((BranchElement)el, index);
+ Edit edit = getEditForParagraphAndIndex((BranchElement) el, index);
edit.addRemovedElements(removed);
edit.addAddedElements(added);
-
- BranchElement newPar =
- (BranchElement) new BranchElement(el.getParentElement(),
- el.getAttributes());
-
+
+ BranchElement newPar = (BranchElement) new BranchElement(el.getParentElement(),
+ el.getAttributes());
+
newPar.replace(0, 0, newAdded);
- res = new Element[]{ null, newPar };
+ res = new Element[] { null, newPar };
}
else
{
@@ -1052,165 +1090,175 @@ public class DefaultStyledDocument extends AbstractDocument
for (int i = index; i < count; ++i)
removed[i - index] = el.getElement(i);
added = new Element[0];
-
- Edit edit = getEditForParagraphAndIndex((BranchElement)el, index);
+
+ Edit edit = getEditForParagraphAndIndex((BranchElement) el, index);
edit.addRemovedElements(removed);
edit.addAddedElements(added);
-
- BranchElement newPar =
- (BranchElement) new BranchElement(el.getParentElement(),
- el.getAttributes());
+
+ BranchElement newPar = (BranchElement) new BranchElement(el.getParentElement(),
+ el.getAttributes());
newPar.replace(0, 0, removed);
- res = new Element[]{ null, newPar };
+ res = new Element[] { null, newPar };
}
}
else if (el instanceof LeafElement)
{
BranchElement par = (BranchElement) el.getParentElement();
- Element el1 = new LeafElement(par, el.getAttributes(),
+ Element el1 = createLeafElement(par, el.getAttributes(),
el.getStartOffset(), offset);
-
- Element el2 = new LeafElement(par, el.getAttributes(),
- offset + space, el.getEndOffset());
- res = new Element[]{ el1, el2 };
+
+ Element el2 = createLeafElement(par, el.getAttributes(), offset
+ + space,
+ el.getEndOffset());
+ res = new Element[] { el1, el2 };
}
return res;
}
-
+
/**
- * Inserts a new paragraph.
+ * Inserts a fracture into the document structure.
*
- * @param par - paragraph to insert new paragraph at.
- * @param offset - offset to insert at.
- * @return new paragraph
+ * @param tag -
+ * the element spec.
*/
- private Element insertParagraph(BranchElement par, int offset)
+ private void insertFracture(ElementSpec tag)
{
- Element current = par.getElement(par.getElementIndex(offset));
- Element[] res = split(current, offset, 0);
- int index = par.getElementIndex(offset);
- Element ret;
- if (res[1] != null)
+ // insert the fracture at offset.
+ BranchElement parent = (BranchElement) elementStack.peek();
+ int parentIndex = parent.getElementIndex(offset);
+ AttributeSet parentAtts = parent.getAttributes();
+ Element toFracture = parent.getElement(parentIndex);
+ int parSize = parent.getElementCount();
+
+ // recreate left-side of branch and all its children before offset
+ // add the fractured leaves to the right branch
+ BranchElement leftBranch = new BranchElement(parent, parentAtts);
+ BranchElement rightBranch = new BranchElement(parent, parentAtts);
+
+ Element frac = toFracture;
+ int leftIns = 0;
+ int indexOfFrac = toFracture.getElementIndex(offset);
+ int size = toFracture.getElementCount();
+ if (!toFracture.isLeaf())
{
- Element[] removed;
- Element[] added;
- if (res[0] == null)
+ // add all non-fracture elements to the branches
+ if (indexOfFrac > 0)
{
- removed = new Element[0];
- if (res[1] instanceof BranchElement)
- {
- added = new Element[]{ res[1] };
- ret = res[1];
- }
- else
- {
- ret = createBranchElement(par, null);
- added = new Element[]{ ret, res[1] };
- }
- index++;
+ Element[] add = new Element[indexOfFrac];
+ for (int i = 0; i < indexOfFrac; i++)
+ add[i] = toFracture.getElement(i);
+ leftIns = add.length;
+ leftBranch.replace(0, 0, add);
}
- else
+
+ int count = size - indexOfFrac - 1;
+ if (count > 0)
{
- removed = new Element[]{ current };
- if (res[1] instanceof BranchElement)
- {
- ret = res[1];
- added = new Element[]{ res[0], res[1] };
- }
- else
- {
- ret = createBranchElement(par, null);
- added = new Element[]{ res[0], ret, res[1] };
- }
+ Element[] add = new Element[count];
+ int j = 0;
+ int i = indexOfFrac + 1;
+ while (j < count)
+ add[j++] = toFracture.getElement(i++);
+ rightBranch.replace(0, 0, add);
}
- Edit edit = getEditForParagraphAndIndex(par, index);
- edit.addRemovedElements(removed);
- edit.addAddedElements(added);
+
+ // gets the leaf that falls along the fracture
+ frac = toFracture.getElement(indexOfFrac);
+ while (!frac.isLeaf())
+ frac = frac.getElement(frac.getElementIndex(offset));
}
- else
+
+ int fracStart = frac.getStartOffset();
+ int fracEnd = frac.getEndOffset();
+ if (fracStart < offset && offset < fracEnd)
{
- ret = createBranchElement(par, null);
- Edit edit = getEditForParagraphAndIndex(par, index);
- edit.addAddedElement(ret);
+ // fracture the leaf and split among 2 branches
+ AttributeSet atts = frac.getAttributes();
+ // replaces old leaf.
+ Element leftFracturedLeaf = createLeafElement(leftBranch, atts,
+ fracStart, offset);
+ leftBranch.replace(leftIns, 0, new Element[] { leftFracturedLeaf });
+
+ // Check if we can join the right frac leaf with the next leaf
+ int rm = 0;
+ int end = fracEnd;
+ Element next = rightBranch.getElement(0);
+ if (next != null && next.isLeaf()
+ && next.getAttributes().isEqual(atts))
+ {
+ end = next.getEndOffset();
+ rm = 1;
+ }
+
+ Element rightFracturedLeaf = createLeafElement(rightBranch, atts,
+ offset, end);
+ rightBranch.replace(0, rm, new Element[] { rightFracturedLeaf });
+
+ // recreate those elements after parentIndex and add/remove all
+ // new/old elements to parent
+ int remove = parSize - parentIndex;
+ Element[] removed = new Element[remove];
+ int s = 0;
+ for (int j = parentIndex; j < parSize; j++)
+ removed[s++] = parent.getElement(j);
+
+ Element[] added = new Element[] { leftBranch, rightBranch };
+ Edit edit = getEditForParagraphAndIndex(parent, parentIndex);
+ edit.addAddedElements(added);
+ edit.addRemovedElements(removed);
+ recreateAfterFracture(removed, parent, 1, rightBranch.getEndOffset());
+ elementStack.push(rightBranch);
+ lastFractured = rightFracturedLeaf;
}
- return ret;
}
-
+
/**
- * Inserts a fracture into the document structure.
+ * Recreates all the elements from the parent to the element on the top of
+ * the stack, starting from startFrom with the starting offset of
+ * startOffset.
*
- * @param tag - the element spec.
+ * @param recreate -
+ * the elements to recreate
+ * @param parent -
+ * the element to add the new elements to
+ * @param startFrom -
+ * where to start recreating from
+ * @param startOffset -
+ * the offset of the first element
*/
- private void insertFracture(ElementSpec tag)
- {
- // The steps we must take to properly fracture are:
- // 1. Recreate the LeafElement at offset to have the correct end offset.
- // 2. Create a new LeafElement with the remainder of the LeafElement in
- // #1 ==> this is whatever was in that LeafElement to the right of the
- // inserted newline.
- // 3. Find the paragraph at offset and remove all its children that
- // occur at and after offset. These will be moved to the newly created
- // paragraph.
- // 4. Move the LeafElement created in #2 and all the LeafElements removed
- // in #3 to the newly created paragraph.
- // 5. Add the new paragraph to the parent.
- BranchElement parent = (BranchElement) elementStack.peek();
- int parentIndex = parent.getElementIndex(offset);
-
- BranchElement previous = (BranchElement) parent.getElement(parentIndex);
- int previousIndex = previous.getElementIndex(offset);
- Element previousLeaf = previous.getElement(previousIndex);
- AttributeSet prevLeafAtts = previous.getAttributes();
- int numReplaced = previous.getElementCount() - previousIndex;
-
- BranchElement newBranch =
- (BranchElement) createBranchElement(parent, prevLeafAtts);
-
- int start = previousLeaf.getStartOffset();
- Element newPreviousLeaf = null;
- if (firstCreated != null && (start != firstCreated.getStartOffset()
- && offset != firstCreated.getEndOffset()))
- {
- newPreviousLeaf = createLeafElement(previous, prevLeafAtts,
- start, offset);
- Edit edit2 = getEditForParagraphAndIndex(previous, previousIndex);
- edit2.addRemovedElement(previousLeaf);
- edit2.addAddedElement(newPreviousLeaf);
- }
-
- // FIXME: This is a workaround... figure out how to determine newEndOffset
- int newEndOffset = Math.min(previousLeaf.getEndOffset(), getLength());
- if (offset == newEndOffset)
- newEndOffset = previousLeaf.getEndOffset();
-
- if (endOffset > offset)
- {
- Element newTempLeaf = createLeafElement(newBranch, prevLeafAtts,
- newEndOffset, newEndOffset + 1);
- newBranch.replace(0, 0, new Element[] { newTempLeaf });
- }
- else
+ private void recreateAfterFracture(Element[] recreate,
+ BranchElement parent, int startFrom,
+ int startOffset)
+ {
+ Element[] added = new Element[recreate.length - startFrom];
+ int j = 0;
+ for (int i = startFrom; i < recreate.length; i++)
{
- Element firstLeafInNewBranch = createLeafElement(newBranch,
- prevLeafAtts,
- offset, newEndOffset);
- Edit edit = getEditForParagraphAndIndex(newBranch, 0);
- Element newLeaves = firstLeafInNewBranch;
- if (newLeaves.getStartOffset() >= endOffset)
- edit.addAddedElement(newLeaves);
- for (int i = 1; i < numReplaced; i++)
+ Element curr = recreate[i];
+ int len = curr.getEndOffset() - curr.getStartOffset();
+ if (curr instanceof LeafElement)
+ added[j] = createLeafElement(parent, curr.getAttributes(),
+ startOffset, startOffset + len);
+ else
{
- newLeaves = previous.getElement(previousIndex + i);
- if (newLeaves.getStartOffset() >= endOffset)
- edit.addAddedElement(newLeaves);
+ BranchElement br = new BranchElement(parent, curr.getAttributes());
+ int bSize = curr.getElementCount();
+ for (int k = 0; k < bSize; k++)
+ {
+ Element bCurr = curr.getElement(k);
+ recreateAfterFracture(new Element[] { bCurr }, br, 0,
+ startOffset);
+ }
+ added[j] = br;
}
+ startOffset += len;
+ j++;
}
-
- Edit edit3 = getEditForParagraphAndIndex(parent, parentIndex + 1);
- edit3.addAddedElement(newBranch);
- elementStack.push(newBranch);
+
+ Edit edit = getEditForParagraphAndIndex(parent, parent.getElementCount());
+ edit.addAddedElements(added);
}
-
+
/**
* Adds an ElementChange for a given element modification to the document
* event. If there already is an ElementChange registered for this element,
@@ -1248,7 +1296,6 @@ public class DefaultStyledDocument extends AbstractDocument
i = ec.getIndex();
}
else
- // FIXME: Not implemented.
throw new AssertionError("Not yet implemented case.");
}
else if (added != null)
@@ -1275,7 +1322,6 @@ public class DefaultStyledDocument extends AbstractDocument
i = ec.getIndex();
}
else
- // FIXME: Not implemented.
throw new AssertionError("Not yet implemented case.");
}
else if (removed != null)
@@ -1486,7 +1532,7 @@ public class DefaultStyledDocument extends AbstractDocument
* name.
*/
protected class SectionElement extends BranchElement
- {
+ {
/**
* Creates a new SectionElement.
*/
@@ -1498,7 +1544,7 @@ public class DefaultStyledDocument extends AbstractDocument
/**
* Returns the name of the element. This method always returns
* &quot;section&quot;.
- *
+ *
* @return the name of the element
*/
public String getName()
@@ -1510,18 +1556,18 @@ public class DefaultStyledDocument extends AbstractDocument
/**
* Receives notification when any of the document's style changes and calls
* {@link DefaultStyledDocument#styleChanged(Style)}.
- *
+ *
* @author Roman Kennke (kennke@aicas.com)
*/
- private class StyleChangeListener
- implements ChangeListener
+ private class StyleChangeListener implements ChangeListener
{
/**
* Receives notification when any of the document's style changes and calls
* {@link DefaultStyledDocument#styleChanged(Style)}.
- *
- * @param event the change event
+ *
+ * @param event
+ * the change event
*/
public void stateChanged(ChangeEvent event)
{
@@ -1548,7 +1594,7 @@ public class DefaultStyledDocument extends AbstractDocument
* Listens for changes on this document's styles and notifies styleChanged().
*/
private StyleChangeListener styleChangeListener;
-
+
/** Vector that contains all the edits. */
Vector edits = new Vector();
@@ -1561,10 +1607,11 @@ public class DefaultStyledDocument extends AbstractDocument
}
/**
- * Creates a new <code>DefaultStyledDocument</code> that uses the
- * specified {@link StyleContext}.
- *
- * @param context the <code>StyleContext</code> to use
+ * Creates a new <code>DefaultStyledDocument</code> that uses the specified
+ * {@link StyleContext}.
+ *
+ * @param context
+ * the <code>StyleContext</code> to use
*/
public DefaultStyledDocument(StyleContext context)
{
@@ -1572,14 +1619,16 @@ public class DefaultStyledDocument extends AbstractDocument
}
/**
- * Creates a new <code>DefaultStyledDocument</code> that uses the
- * specified {@link StyleContext} and {@link Content} buffer.
- *
- * @param content the <code>Content</code> buffer to use
- * @param context the <code>StyleContext</code> to use
+ * Creates a new <code>DefaultStyledDocument</code> that uses the specified
+ * {@link StyleContext} and {@link Content} buffer.
+ *
+ * @param content
+ * the <code>Content</code> buffer to use
+ * @param context
+ * the <code>StyleContext</code> to use
*/
public DefaultStyledDocument(AbstractDocument.Content content,
- StyleContext context)
+ StyleContext context)
{
super(content, context);
buffer = new ElementBuffer(createDefaultRoot());
@@ -1587,10 +1636,9 @@ public class DefaultStyledDocument extends AbstractDocument
}
/**
- * Adds a style into the style hierarchy. Unspecified style attributes
- * can be resolved in the <code>parent</code> style, if one is specified.
- *
- * While it is legal to add nameless styles (<code>nm == null</code),
+ * Adds a style into the style hierarchy. Unspecified style attributes can be
+ * resolved in the <code>parent</code> style, if one is specified. While it
+ * is legal to add nameless styles (<code>nm == null</code),
* you must be aware that the client application is then responsible
* for managing the style hierarchy, since unnamed styles cannot be
* looked up by their name.
@@ -1617,7 +1665,7 @@ public class DefaultStyledDocument extends AbstractDocument
/**
* Create the default root element for this kind of <code>Document</code>.
- *
+ *
* @return the default root element for this kind of <code>Document</code>
*/
protected AbstractDocument.AbstractElement createDefaultRoot()
@@ -1639,14 +1687,14 @@ public class DefaultStyledDocument extends AbstractDocument
}
/**
- * Returns the <code>Element</code> that corresponds to the character
- * at the specified position.
- *
- * @param position the position of which we query the corresponding
- * <code>Element</code>
- *
- * @return the <code>Element</code> that corresponds to the character
- * at the specified position
+ * Returns the <code>Element</code> that corresponds to the character at the
+ * specified position.
+ *
+ * @param position
+ * the position of which we query the corresponding
+ * <code>Element</code>
+ * @return the <code>Element</code> that corresponds to the character at the
+ * specified position
*/
public Element getCharacterElement(int position)
{
@@ -1657,15 +1705,15 @@ public class DefaultStyledDocument extends AbstractDocument
int index = element.getElementIndex(position);
element = element.getElement(index);
}
-
+
return element;
}
/**
* Extracts a background color from a set of attributes.
- *
- * @param attributes the attributes from which to get a background color
- *
+ *
+ * @param attributes
+ * the attributes from which to get a background color
* @return the background color that correspond to the attributes
*/
public Color getBackground(AttributeSet attributes)
@@ -1676,7 +1724,7 @@ public class DefaultStyledDocument extends AbstractDocument
/**
* Returns the default root element.
- *
+ *
* @return the default root element
*/
public Element getDefaultRootElement()
@@ -1686,9 +1734,9 @@ public class DefaultStyledDocument extends AbstractDocument
/**
* Extracts a font from a set of attributes.
- *
- * @param attributes the attributes from which to get a font
- *
+ *
+ * @param attributes
+ * the attributes from which to get a font
* @return the font that correspond to the attributes
*/
public Font getFont(AttributeSet attributes)
@@ -1696,12 +1744,12 @@ public class DefaultStyledDocument extends AbstractDocument
StyleContext context = (StyleContext) getAttributeContext();
return context.getFont(attributes);
}
-
+
/**
* Extracts a foreground color from a set of attributes.
- *
- * @param attributes the attributes from which to get a foreground color
- *
+ *
+ * @param attributes
+ * the attributes from which to get a foreground color
* @return the foreground color that correspond to the attributes
*/
public Color getForeground(AttributeSet attributes)
@@ -1712,9 +1760,9 @@ public class DefaultStyledDocument extends AbstractDocument
/**
* Returns the logical <code>Style</code> for the specified position.
- *
- * @param position the position from which to query to logical style
- *
+ *
+ * @param position
+ * the position from which to query to logical style
* @return the logical <code>Style</code> for the specified position
*/
public Style getLogicalStyle(int position)
@@ -1729,37 +1777,32 @@ public class DefaultStyledDocument extends AbstractDocument
}
/**
- * Returns the paragraph element for the specified position.
- * If the position is outside the bounds of the document's root element,
- * then the closest element is returned. That is the last paragraph if
+ * Returns the paragraph element for the specified position. If the position
+ * is outside the bounds of the document's root element, then the closest
+ * element is returned. That is the last paragraph if
* <code>position >= endIndex</code> or the first paragraph if
* <code>position < startIndex</code>.
- *
- * @param position the position for which to query the paragraph element
- *
+ *
+ * @param position
+ * the position for which to query the paragraph element
* @return the paragraph element for the specified position
*/
public Element getParagraphElement(int position)
{
- BranchElement root = (BranchElement) getDefaultRootElement();
- int start = root.getStartOffset();
- int end = root.getEndOffset();
- if (position >= end)
- position = end - 1;
- else if (position < start)
- position = start;
-
- Element par = root.positionToElement(position);
-
- assert par != null : "The paragraph element must not be null";
- return par;
+ Element e = getDefaultRootElement();
+ while (!e.isLeaf())
+ e = e.getElement(e.getElementIndex(position));
+
+ if (e != null)
+ return e.getParentElement();
+ return e;
}
/**
* Looks up and returns a named <code>Style</code>.
- *
- * @param nm the name of the <code>Style</code>
- *
+ *
+ * @param nm
+ * the name of the <code>Style</code>
* @return the found <code>Style</code> of <code>null</code> if no such
* <code>Style</code> exists
*/
@@ -1771,8 +1814,9 @@ public class DefaultStyledDocument extends AbstractDocument
/**
* Removes a named <code>Style</code> from the style hierarchy.
- *
- * @param nm the name of the <code>Style</code> to be removed
+ *
+ * @param nm
+ * the name of the <code>Style</code> to be removed
*/
public void removeStyle(String nm)
{
@@ -1783,31 +1827,33 @@ public class DefaultStyledDocument extends AbstractDocument
/**
* Sets text attributes for the fragment specified by <code>offset</code>
* and <code>length</code>.
- *
- * @param offset the start offset of the fragment
- * @param length the length of the fragment
- * @param attributes the text attributes to set
- * @param replace if <code>true</code>, the attributes of the current
- * selection are overridden, otherwise they are merged
+ *
+ * @param offset
+ * the start offset of the fragment
+ * @param length
+ * the length of the fragment
+ * @param attributes
+ * the text attributes to set
+ * @param replace
+ * if <code>true</code>, the attributes of the current selection
+ * are overridden, otherwise they are merged
*/
public void setCharacterAttributes(int offset, int length,
- AttributeSet attributes,
- boolean replace)
+ AttributeSet attributes, boolean replace)
{
// Exit early if length is 0, so no DocumentEvent is created or fired.
if (length == 0)
return;
try
{
- // Must obtain a write lock for this method. writeLock() and
+ // Must obtain a write lock for this method. writeLock() and
// writeUnlock() should always be in try/finally block to make
// sure that locking happens in a balanced manner.
writeLock();
- DefaultDocumentEvent ev =
- new DefaultDocumentEvent(
- offset,
- length,
- DocumentEvent.EventType.CHANGE);
+ DefaultDocumentEvent ev = new DefaultDocumentEvent(
+ offset,
+ length,
+ DocumentEvent.EventType.CHANGE);
// Modify the element structure so that the interval begins at an
// element
@@ -1818,13 +1864,13 @@ public class DefaultStyledDocument extends AbstractDocument
// Visit all paragraph elements within the specified interval
int end = offset + length;
Element curr;
- for (int pos = offset; pos < end; )
+ for (int pos = offset; pos < end;)
{
// Get the CharacterElement at offset pos.
curr = getCharacterElement(pos);
if (pos == curr.getEndOffset())
break;
-
+
MutableAttributeSet a = (MutableAttributeSet) curr.getAttributes();
ev.addEdit(new AttributeUndoableEdit(curr, attributes, replace));
// If replace is true, remove all the old attributes.
@@ -1843,12 +1889,14 @@ public class DefaultStyledDocument extends AbstractDocument
writeUnlock();
}
}
-
+
/**
* Sets the logical style for the paragraph at the specified position.
- *
- * @param position the position at which the logical style is added
- * @param style the style to set for the current paragraph
+ *
+ * @param position
+ * the position at which the logical style is added
+ * @param style
+ * the style to set for the current paragraph
*/
public void setLogicalStyle(int position, Style style)
{
@@ -1858,59 +1906,61 @@ public class DefaultStyledDocument extends AbstractDocument
if (el == null)
return;
try
- {
- writeLock();
- if (el instanceof AbstractElement)
- {
- AbstractElement ael = (AbstractElement) el;
- ael.setResolveParent(style);
- int start = el.getStartOffset();
- int end = el.getEndOffset();
- DefaultDocumentEvent ev =
- new DefaultDocumentEvent (start,
- end - start,
- DocumentEvent.EventType.CHANGE);
- fireChangedUpdate(ev);
- fireUndoableEditUpdate(new UndoableEditEvent(this, ev));
- }
- else
- throw new
- AssertionError("paragraph elements are expected to be"
- + "instances of AbstractDocument.AbstractElement");
- }
+ {
+ writeLock();
+ if (el instanceof AbstractElement)
+ {
+ AbstractElement ael = (AbstractElement) el;
+ ael.setResolveParent(style);
+ int start = el.getStartOffset();
+ int end = el.getEndOffset();
+ DefaultDocumentEvent ev = new DefaultDocumentEvent(
+ start,
+ end - start,
+ DocumentEvent.EventType.CHANGE);
+ fireChangedUpdate(ev);
+ fireUndoableEditUpdate(new UndoableEditEvent(this, ev));
+ }
+ else
+ throw new AssertionError(
+ "paragraph elements are expected to be"
+ + "instances of AbstractDocument.AbstractElement");
+ }
finally
- {
- writeUnlock();
- }
+ {
+ writeUnlock();
+ }
}
/**
* Sets text attributes for the paragraph at the specified fragment.
- *
- * @param offset the beginning of the fragment
- * @param length the length of the fragment
- * @param attributes the text attributes to set
- * @param replace if <code>true</code>, the attributes of the current
- * selection are overridden, otherwise they are merged
+ *
+ * @param offset
+ * the beginning of the fragment
+ * @param length
+ * the length of the fragment
+ * @param attributes
+ * the text attributes to set
+ * @param replace
+ * if <code>true</code>, the attributes of the current selection
+ * are overridden, otherwise they are merged
*/
public void setParagraphAttributes(int offset, int length,
- AttributeSet attributes,
- boolean replace)
+ AttributeSet attributes, boolean replace)
{
try
{
- // Must obtain a write lock for this method. writeLock() and
+ // Must obtain a write lock for this method. writeLock() and
// writeUnlock() should always be in try/finally blocks to make
// sure that locking occurs in a balanced manner.
writeLock();
-
+
// Create a DocumentEvent to use for changedUpdate().
- DefaultDocumentEvent ev =
- new DefaultDocumentEvent (
- offset,
- length,
- DocumentEvent.EventType.CHANGE);
-
+ DefaultDocumentEvent ev = new DefaultDocumentEvent(
+ offset,
+ length,
+ DocumentEvent.EventType.CHANGE);
+
// Have to iterate through all the _paragraph_ elements that are
// contained or partially contained in the interval
// (offset, offset + length).
@@ -1919,7 +1969,7 @@ public class DefaultStyledDocument extends AbstractDocument
int endElement = rootElement.getElementIndex(offset + length - 1);
if (endElement < startElement)
endElement = startElement;
-
+
for (int i = startElement; i <= endElement; i++)
{
Element par = rootElement.getElement(i);
@@ -1942,11 +1992,13 @@ public class DefaultStyledDocument extends AbstractDocument
}
/**
- * Called in response to content insert actions. This is used to
- * update the element structure.
- *
- * @param ev the <code>DocumentEvent</code> describing the change
- * @param attr the attributes for the change
+ * Called in response to content insert actions. This is used to update the
+ * element structure.
+ *
+ * @param ev
+ * the <code>DocumentEvent</code> describing the change
+ * @param attr
+ * the attributes for the change
*/
protected void insertUpdate(DefaultDocumentEvent ev, AttributeSet attr)
{
@@ -1957,8 +2009,7 @@ public class DefaultStyledDocument extends AbstractDocument
int offset = ev.getOffset();
int length = ev.getLength();
int endOffset = offset + length;
- AttributeSet paragraphAttributes =
- getParagraphElement(endOffset).getAttributes();
+ AttributeSet paragraphAttributes = getParagraphElement(endOffset).getAttributes();
Segment txt = new Segment();
try
{
@@ -1977,77 +2028,75 @@ public class DefaultStyledDocument extends AbstractDocument
short finalStartDirection = ElementSpec.OriginateDirection;
boolean prevCharWasNewline = false;
Element prev = getCharacterElement(offset);
- Element next = getCharacterElement(endOffset);
+ Element next = getCharacterElement(endOffset);
Element prevParagraph = getParagraphElement(offset);
Element paragraph = getParagraphElement(endOffset);
-
+
int segmentEnd = txt.offset + txt.count;
-
+
// Check to see if we're inserting immediately after a newline.
if (offset > 0)
{
try
- {
- String s = getText(offset - 1, 1);
- if (s.equals("\n"))
- {
- finalStartDirection =
- handleInsertAfterNewline(specs, offset, endOffset,
- prevParagraph,
- paragraph,
- paragraphAttributes);
-
- prevCharWasNewline = true;
- // Find the final start tag from the ones just created.
- for (int i = 0; i < specs.size(); i++)
- if (((ElementSpec) specs.get(i)).getType()
- == ElementSpec.StartTagType)
- finalStartTag = (ElementSpec)specs.get(i);
- }
- }
+ {
+ String s = getText(offset - 1, 1);
+ if (s.equals("\n"))
+ {
+ finalStartDirection = handleInsertAfterNewline(specs, offset,
+ endOffset,
+ prevParagraph,
+ paragraph,
+ paragraphAttributes);
+
+ prevCharWasNewline = true;
+ // Find the final start tag from the ones just created.
+ for (int i = 0; i < specs.size(); i++)
+ if (((ElementSpec) specs.get(i)).getType() == ElementSpec.StartTagType)
+ finalStartTag = (ElementSpec) specs.get(i);
+ }
+ }
catch (BadLocationException ble)
- {
- // This shouldn't happen.
- AssertionError ae = new AssertionError();
- ae.initCause(ble);
- throw ae;
- }
+ {
+ // This shouldn't happen.
+ AssertionError ae = new AssertionError();
+ ae.initCause(ble);
+ throw ae;
+ }
}
-
for (int i = txt.offset; i < segmentEnd; ++i)
{
len++;
if (txt.array[i] == '\n')
{
// Add the ElementSpec for the content.
- specs.add(new ElementSpec(attr, ElementSpec.ContentType, len));
+ specs.add(new ElementSpec(attr, ElementSpec.ContentType, len));
// Add ElementSpecs for the newline.
specs.add(new ElementSpec(null, ElementSpec.EndTagType));
finalStartTag = new ElementSpec(paragraphAttributes,
- ElementSpec.StartTagType);
+ ElementSpec.StartTagType);
specs.add(finalStartTag);
len = 0;
}
}
// Create last element if last character hasn't been a newline.
- if (len > 0)
+ if (len > 0)
specs.add(new ElementSpec(attr, ElementSpec.ContentType, len));
- // Set the direction of the last spec of type StartTagType.
- // If we are inserting after a newline then this value comes from
+ // Set the direction of the last spec of type StartTagType.
+ // If we are inserting after a newline then this value comes from
// handleInsertAfterNewline.
if (finalStartTag != null)
- {
+ {
if (prevCharWasNewline)
finalStartTag.setDirection(finalStartDirection);
else if (prevParagraph.getEndOffset() != endOffset)
finalStartTag.setDirection(ElementSpec.JoinFractureDirection);
else
{
- // If there is an element AFTER this one, then set the
+ // If there is an element AFTER this one, then set the
// direction to JoinNextDirection.
Element parent = prevParagraph.getParentElement();
int index = parent.getElementIndex(offset);
@@ -2056,19 +2105,18 @@ public class DefaultStyledDocument extends AbstractDocument
finalStartTag.setDirection(ElementSpec.JoinNextDirection);
}
}
-
+
// If we are at the last index, then check if we could probably be
// joined with the next element.
// This means:
- // - we must be a ContentTag
- // - if there is a next Element, we must have the same attributes
- // - if there is no next Element, but one will be created,
- // we must have the same attributes as the higher-level run.
+ // - we must be a ContentTag
+ // - if there is a next Element, we must have the same attributes
+ // - if there is no next Element, but one will be created,
+ // we must have the same attributes as the higher-level run.
ElementSpec last = (ElementSpec) specs.lastElement();
if (last.getType() == ElementSpec.ContentType)
{
- Element currentRun =
- prevParagraph.getElement(prevParagraph.getElementIndex(offset));
+ Element currentRun = prevParagraph.getElement(prevParagraph.getElementIndex(offset));
if (currentRun.getEndOffset() == endOffset)
{
if (endOffset < getLength() && next.getAttributes().isEqual(attr)
@@ -2078,36 +2126,36 @@ public class DefaultStyledDocument extends AbstractDocument
else
{
if (finalStartTag != null
- && finalStartTag.getDirection() ==
- ElementSpec.JoinFractureDirection
+ && finalStartTag.getDirection() == ElementSpec.JoinFractureDirection
&& currentRun.getAttributes().isEqual(attr))
{
last.setDirection(ElementSpec.JoinNextDirection);
}
}
}
-
+
// If we are at the first new element, then check if it could be
// joined with the previous element.
ElementSpec first = (ElementSpec) specs.firstElement();
if (prev.getAttributes().isEqual(attr)
&& first.getType() == ElementSpec.ContentType)
first.setDirection(ElementSpec.JoinPreviousDirection);
-
- ElementSpec[] elSpecs =
- (ElementSpec[]) specs.toArray(new ElementSpec[specs.size()]);
+
+ ElementSpec[] elSpecs = (ElementSpec[]) specs.toArray(new ElementSpec[specs.size()]);
buffer.insert(offset, length, elSpecs, ev);
}
/**
- * A helper method to set up the ElementSpec buffer for the special
- * case of an insertion occurring immediately after a newline.
- * @param specs the ElementSpec buffer to initialize.
+ * A helper method to set up the ElementSpec buffer for the special case of an
+ * insertion occurring immediately after a newline.
+ *
+ * @param specs
+ * the ElementSpec buffer to initialize.
*/
short handleInsertAfterNewline(Vector specs, int offset, int endOffset,
- Element prevParagraph, Element paragraph,
- AttributeSet a)
+ Element prevParagraph, Element paragraph,
+ AttributeSet a)
{
if (prevParagraph.getParentElement() == paragraph.getParentElement())
{
@@ -2117,23 +2165,25 @@ public class DefaultStyledDocument extends AbstractDocument
return ElementSpec.JoinFractureDirection;
// If there is an Element after this one, use JoinNextDirection.
Element parent = paragraph.getParentElement();
- if (parent.getElementCount() > parent.getElementIndex(offset) + 1)
+ if (parent.getElementCount() > (parent.getElementIndex(offset) + 1))
return ElementSpec.JoinNextDirection;
}
else
{
- // TODO: What to do here?
+ // FIXME: What to do here?
+ System.out.println("handleInsertAfterNewline: else reached -> Not implemented.");
}
return ElementSpec.OriginateDirection;
}
-
+
/**
* Updates the document structure in response to text removal. This is
- * forwarded to the {@link ElementBuffer} of this document. Any changes to
- * the document structure are added to the specified document event and
- * sent to registered listeners.
- *
- * @param ev the document event that records the changes to the document
+ * forwarded to the {@link ElementBuffer} of this document. Any changes to the
+ * document structure are added to the specified document event and sent to
+ * registered listeners.
+ *
+ * @param ev
+ * the document event that records the changes to the document
*/
protected void removeUpdate(DefaultDocumentEvent ev)
{
@@ -2143,7 +2193,7 @@ public class DefaultStyledDocument extends AbstractDocument
/**
* Returns an enumeration of all style names.
- *
+ *
* @return an enumeration of all style names
*/
public Enumeration getStyleNames()
@@ -2154,32 +2204,35 @@ public class DefaultStyledDocument extends AbstractDocument
/**
* Called when any of this document's styles changes.
- *
- * @param style the style that changed
+ *
+ * @param style
+ * the style that changed
*/
protected void styleChanged(Style style)
{
// Nothing to do here. This is intended to be overridden by subclasses.
}
-
+
/**
* Inserts a bulk of structured content at once.
- *
- * @param offset the offset at which the content should be inserted
- * @param data the actual content spec to be inserted
+ *
+ * @param offset
+ * the offset at which the content should be inserted
+ * @param data
+ * the actual content spec to be inserted
*/
protected void insert(int offset, ElementSpec[] data)
- throws BadLocationException
+ throws BadLocationException
{
if (data == null || data.length == 0)
return;
try
{
// writeLock() and writeUnlock() should always be in a try/finally
- // block so that locking balance is guaranteed even if some
+ // block so that locking balance is guaranteed even if some
// exception is thrown.
writeLock();
-
+
// First we collect the content to be inserted.
StringBuffer contentBuffer = new StringBuffer();
for (int i = 0; i < data.length; i++)
@@ -2197,15 +2250,15 @@ public class DefaultStyledDocument extends AbstractDocument
// If there was no content inserted then exit early.
if (length == 0)
return;
-
+
UndoableEdit edit = content.insertString(offset,
contentBuffer.toString());
// Create the DocumentEvent with the ElementEdit added
- DefaultDocumentEvent ev =
- new DefaultDocumentEvent(offset,
- length,
- DocumentEvent.EventType.INSERT);
+ DefaultDocumentEvent ev = new DefaultDocumentEvent(
+ offset,
+ length,
+ DocumentEvent.EventType.INSERT);
ev.addEdit(edit);
// Finally we must update the document structure and fire the insert
@@ -2223,9 +2276,10 @@ public class DefaultStyledDocument extends AbstractDocument
/**
* Initializes the <code>DefaultStyledDocument</code> with the specified
* data.
- *
- * @param data the specification of the content with which the document is
- * initialized
+ *
+ * @param data
+ * the specification of the content with which the document is
+ * initialized
*/
protected void create(ElementSpec[] data)
{