You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by ml...@apache.org on 2006/07/31 16:08:55 UTC
svn commit: r427121 [2/29] - in
/incubator/harmony/enhanced/classlib/trunk/modules/swing: make/
src/main/java/common/javax/swing/ src/main/java/common/javax/swing/text/
src/main/java/common/javax/swing/text/html/
src/main/java/common/javax/swing/text/h...
Modified: incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/DefaultStyledDocument.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/DefaultStyledDocument.java?rev=427121&r1=427120&r2=427121&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/DefaultStyledDocument.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/DefaultStyledDocument.java Mon Jul 31 07:08:47 2006
@@ -82,6 +82,7 @@
private transient Stack changeStack;
private transient List changes;
private transient boolean create;
+ private transient Element tail;
public ElementBuffer(final Element root) {
this.root = root;
@@ -145,67 +146,38 @@
protected void insertUpdate(final ElementSpec[] spec) {
// Find the deepest branch
- BranchElement branch = (BranchElement)root;
- Element child;
+ Element branch = root;
do {
changeStack.push(new ChangeDesc(branch));
- child = branch.getElement(branch.getElementIndex(offset));
- if (!child.isLeaf()) {
- branch = (BranchElement)child;
- }
- } while (!child.isLeaf());
+ branch = branch.getElement(branch.getElementIndex(offset));
+ } while (!branch.isLeaf());
current = (ChangeDesc)changeStack.peek();
- //Element leaf = getCharacterElement(offset);
- //current = (BranchElement)leaf.getParentElement();
-
- // Apply each spec to the tree
- for (int i = 0; i < spec.length; i++) {
- switch (spec[i].getType()) {
- case ElementSpec.ContentType:
- insertContent(spec[i]);
- break;
-
- case ElementSpec.EndTagType:
- insertEndTag();
- break;
- case ElementSpec.StartTagType:
- insertStartTag(spec[i]);
- break;
-
- default:
- throw new Error("Unknown type in the spec");
- }
- }
+ performSpecs(spec);
leaveParagraph();
}
protected void removeUpdate() {
final int endOffset = offset + length;
final Element startLeaf = getCharacterElement(offset);
+ final Element startBranch = startLeaf.getParentElement();
+
final Element endLeaf = endOffset == startLeaf.getEndOffset()
- && endOffset < startLeaf.getParentElement()
- .getEndOffset()
+ && endOffset < startBranch.getEndOffset()
? startLeaf
: getCharacterElement(endOffset);
+ final Element endBranch = endLeaf.getParentElement();
if (startLeaf == endLeaf) {
if (startLeaf.getStartOffset() == offset
&& endOffset == startLeaf.getEndOffset()) {
- current = new ChangeDesc(startLeaf.getParentElement());
- current.setIndex(current.element.getElementIndex(offset));
+ current = new ChangeDesc(startBranch, offset);
current.removed.add(startLeaf);
changes.add(current);
}
- return;
- }
-
- final Element startBranch = startLeaf.getParentElement();
- final Element endBranch = endLeaf.getParentElement();
-
- if (startBranch == endBranch) {
+ } else if (startBranch == endBranch) {
final int index = startBranch.getElementIndex(offset);
current = new ChangeDesc(startBranch);
for (int i = index; i < startBranch.getElementCount(); i++) {
@@ -213,9 +185,7 @@
if (offset <= child.getStartOffset()
&& child.getEndOffset() <= endOffset) {
- if (current.getIndex() < 0) {
- current.setIndex(i);
- }
+ current.setChildIndex(i);
current.removed.add(child);
}
if (endOffset < child.getEndOffset()) {
@@ -227,39 +197,55 @@
} else {
final BranchElement parent =
(BranchElement)startBranch.getParentElement();
- current = new ChangeDesc(parent);
- current.setIndex(parent.getElementIndex(offset));
-
- final BranchElement branch =
- (BranchElement)createBranchElement(parent,
- startBranch
- .getAttributes());
-
- List children = new LinkedList();
-
- // Copy elements from startBranch
- int index = startBranch.getElementIndex(offset);
- if (startBranch.getElement(index).getStartOffset() < offset) {
- ++index;
- }
- for (int i = 0; i < index; i++) {
- children.add(clone(branch, startBranch.getElement(i)));
- }
-
- // Copy elements from endBranch
- index = endBranch.getElementIndex(endOffset);
- for (int i = index; i < endBranch.getElementCount(); i++) {
- children.add(clone(branch, endBranch.getElement(i)));
+ if (parent != null) {
+ current = new ChangeDesc(parent, offset);
+
+ BranchElement branch = (BranchElement)createBranchElement(parent,
+ startBranch.getAttributes());
+ List children = new LinkedList();
+
+ // Copy elements from startBranch
+ int index = startBranch.getElementIndex(offset);
+ if (startBranch.getElement(index).getStartOffset() < offset) {
+ ++index;
+ }
+ for (int i = 0; i < index; i++) {
+ children.add(clone(branch, startBranch.getElement(i)));
+ }
+
+ // Copy elements from endBranch
+ index = endBranch.getElementIndex(endOffset);
+ for (int i = index; i < endBranch.getElementCount(); i++) {
+ children.add(clone(branch, endBranch.getElement(i)));
+ }
+
+ index = parent.getElementIndex(endOffset);
+ for (int i = current.getChildIndex(); i <= index; i++) {
+ current.removeChildElement(i);
+ }
+ current.added.add(branch);
+
+ branch.replace(0, 0, listToElementArray(children));
+ } else {
+ current = new ChangeDesc(startBranch, offset);
+
+ // Copy elements from endBranch
+ int index = endBranch.getElementIndex(endOffset);
+ for (int i = index; i < endBranch.getElementCount(); i++) {
+ current.added.add(clone(startBranch, endBranch.getElement(i)));
+ }
+
+ // Copy elements from startBranch
+ int startIndex = startBranch.getElementIndex(offset);
+ int endIndex = startBranch.getElementIndex(endOffset);
+ for (int i = startIndex; i <= endIndex; i++) {
+ current.removeChildElement(i);
+ }
+ current.setChildIndex(startIndex);
+
+ current.apply();
}
- index = parent.getElementIndex(endOffset);
- for (int i = current.getIndex(); i <= index; i++) {
- current.removed.add(parent.getElement(i));
- }
- current.added.add(branch);
-
- branch.replace(0, 0, listToElementArray(children));
-
changes.add(current);
}
}
@@ -275,77 +261,42 @@
}
if (startLeaf == endLeaf) {
- final int start = startLeaf.getStartOffset();
- final int end = startLeaf.getEndOffset();
- if (start == offset && endOffset == end) {
- return;
- }
- final AttributeSet attrs = startLeaf.getAttributes();
-
- current = new ChangeDesc(startLeaf.getParentElement());
- current.setIndex(current.element.getElementIndex(offset));
- current.removed.add(startLeaf);
-
- if (startLeaf.getStartOffset() < offset) {
- current.added.add(createLeafElement(current.element, attrs,
- start, offset));
- }
- current.added.add(createLeafElement(current.element, attrs,
- offset, endOffset));
- if (endOffset < end) {
- current.added.add(createLeafElement(current.element, attrs,
- endOffset, end));
- }
+ current = new ChangeDesc(startLeaf.getParentElement(), offset);
+ current.splitLeafElement(startLeaf, offset, endOffset, true, startLeaf.getAttributes());
changes.add(current);
} else {
// Break the startLeaf
int start = startLeaf.getStartOffset();
int end = startLeaf.getEndOffset();
- AttributeSet attrs = startLeaf.getAttributes();
if (start < offset) {
- current = new ChangeDesc(startLeaf.getParentElement());
- current.setIndex(current.element.getElementIndex(offset));
- current.removed.add(startLeaf);
-
- current.added.add(createLeafElement(current.element, attrs,
- start, offset));
- current.added.add(createLeafElement(current.element, attrs,
- offset, end));
+ current = new ChangeDesc(startLeaf.getParentElement(), offset);
+ current.splitLeafElement(startLeaf, offset);
changes.add(current);
}
// Break the endLeaf
start = endLeaf.getStartOffset();
end = endLeaf.getEndOffset();
- attrs = endLeaf.getAttributes();
if (start < endOffset && endOffset < end) {
final boolean sameParents = current != null
&& current.element == endLeaf.getParentElement();
if (!sameParents) {
- current = new ChangeDesc(endLeaf.getParentElement());
- current.setIndex(current.element
- .getElementIndex(endOffset));
+ current = new ChangeDesc(endLeaf.getParentElement(), endOffset);
} else {
- final int endIndex = current.element
- .getElementIndex(endOffset);
- for (int i = current.getIndex() + 1;
+ final int endIndex = current.getChildIndexAtOffset(endOffset);
+ for (int i = current.getChildIndex() + 1;
i < endIndex; i++) {
- final Element child = current.element.getElement(i);
+ final Element child = current.getChildElement(i);
current.removed.add(child);
current.added.add(child);
}
}
- current.removed.add(endLeaf);
-
- current.added.add(createLeafElement(current.element, attrs,
- start, endOffset));
- current.added.add(createLeafElement(current.element, attrs,
- endOffset, end));
+ current.splitLeafElement(endLeaf, endOffset);
if (!sameParents) {
changes.add(current);
@@ -361,23 +312,27 @@
// Remove all elements from the only paragraph
current = new ChangeDesc(getParagraphElement(0));
- current.setIndex(0);
- current.added.add(createLeafElement(current.element,
- current.element
- .getElement(0).getAttributes(),
- length, length + 1));
+ current.setChildIndex(0);
+ current.createLeafElement(current.getChildElement(0).getAttributes(),
+ length, length + 1);
for (int i = 0; i < current.element.getElementCount(); i++) {
- current.removed.add(current.element.getElement(i));
+ current.removeChildElement(i);
}
current.apply();
changes.add(current);
current = null;
- // Apply each spec to the tree
- for (int i = 0; i < specs.length; i++) {
- switch (specs[i].getType()) {
+ performSpecs(specs);
+ leaveParagraph();
+
+ collectEdits();
+ }
+
+ private void performSpecs(final ElementSpec[] spec) throws Error {
+ for (int i = 0; i < spec.length; i++) {
+ switch (spec[i].getType()) {
case ElementSpec.ContentType:
- insertContent(specs[i]);
+ insertContent(spec[i]);
break;
case ElementSpec.EndTagType:
@@ -385,16 +340,13 @@
break;
case ElementSpec.StartTagType:
- insertStartTag(specs[i]);
+ insertStartTag(spec[i]);
break;
default:
throw new Error("Unknown type in the spec");
}
}
- leaveParagraph();
-
- collectEdits();
}
private void applyEdits() {
@@ -419,6 +371,13 @@
}
}
changes.clear();
+
+ clear();
+ }
+
+ private void clear() {
+ event = null;
+ current = null;
}
private void insertContent(final ElementSpec spec) {
@@ -443,64 +402,66 @@
}
private void insertContentOriginate(final ElementSpec spec) {
- // First we should remove the element that was at the place
+ final AttributeSet specAttr = spec.getAttributes();
if (current.element.getElementCount() == 0) {
- if (current.getIndex() < 0) {
- current.setIndex(0);
+ current.setChildIndex(0);
+ current.createLeafElement(specAttr,
+ offset, offset + spec.length);
+ } else {
+ current.setChildIndexByOffset(offset);
+ final Element leafToRemove = current.getCurrentChild();
+ if (offset == 0 && leafToRemove.isLeaf()) {
+ current.removed.add(leafToRemove);
+ current.createLeafElement(specAttr,
+ offset, offset + spec.length);
+ current.createLeafElement(leafToRemove.getAttributes(),
+ offset + length, leafToRemove.getEndOffset());
+ tail = current.getLastAddedElement();
+ current.added.remove(tail);
+ } else if (offset == event.getOffset()
+ && leafToRemove.getStartOffset() < offset
+ && offset < leafToRemove.getEndOffset()) {
+ if (leafToRemove.isLeaf()) {
+ current.splitLeafElement(leafToRemove, offset,
+ offset + spec.length,
+ offset + length,
+ true, specAttr);
+ tail = current.getLastAddedElement();
+ current.added.remove(tail);
+ } else {
+ tail = splitBranch(leafToRemove);
+ current.createLeafElement(specAttr,
+ offset, offset + spec.length);
+ current.childIndex = current.getChildIndex() + 1;
+ }
+ } else {
+ current.createLeafElement(specAttr,
+ offset, offset + spec.length);
+ if (offset >= current.element.getEndOffset()
+ && current.getChildIndex() < current.element
+ .getElementCount()) {
+ current.childIndex = current.getChildIndex() + 1;
+ }
}
- current.added.add(createLeafElement(current.element,
- spec.getAttributes(),
- offset,
- offset + spec.getLength()));
- return;
}
-
- if (current.getIndex() < 0) {
- current.setIndex(current.element.getElementIndex(offset));
- }
- final Element leafToRemove = current.element
- .getElement(current.getIndex());
-
- if (offset == 0) {
- current.removed.add(leafToRemove);
- } else if (offset == event.getOffset()
- && leafToRemove.getStartOffset() < offset
- && offset < leafToRemove.getEndOffset()) {
- current.removed.add(leafToRemove);
- current.added.add(createLeafElement(current.element,
- leafToRemove.getAttributes(),
- leafToRemove.getStartOffset(),
- offset));
- }
- current.added.add(createLeafElement(current.element,
- spec.getAttributes(),
- offset, offset + spec.length));
}
private void insertContentJoinNext(final ElementSpec spec) {
- if (current.getIndex() < 0) {
- current.setIndex(current.element.getElementIndex(offset));
- }
- final Element leaf = current.element.getElement(current.getIndex());
+ current.setChildIndexByOffset(offset);
+ final Element leaf = current.getCurrentChild();
if (leaf.getStartOffset() >= offset) {
current.removed.add(leaf);
- current.added.add(createLeafElement(current.element,
- leaf.getAttributes(),
- offset,
- leaf.getEndOffset()));
+ current.createLeafElement(leaf.getAttributes(),
+ offset, leaf.getEndOffset());
} else {
final Element next =
- current.element.getElement(current.getIndex() + 1);
+ current.getChildElement(current.getChildIndex() + 1);
current.removed.add(leaf);
current.removed.add(next);
- current.added.add(createLeafElement(current.element,
- leaf.getAttributes(),
- leaf.getStartOffset(),
- offset));
- current.added.add(createLeafElement(current.element,
- next.getAttributes(),
- offset,
- next.getEndOffset()));
+ current.createLeafElement(leaf.getAttributes(),
+ leaf.getStartOffset(), offset);
+ current.createLeafElement(next.getAttributes(),
+ offset, next.getEndOffset());
}
}
@@ -515,7 +476,7 @@
break;
case ElementSpec.JoinPreviousDirection:
- insertStartJoinPrevious();
+ insertStartJoinPrevious(spec);
break;
case ElementSpec.JoinFractureDirection:
@@ -528,93 +489,87 @@
}
private void insertStartFracture(final ElementSpec spec) {
- final ChangeDesc lastChange = (ChangeDesc)changes.get(changes.size()
- - 1);
- final BranchElement lastBranch = lastChange.element;
final AttributeSet attrs =
spec.getDirection() == ElementSpec.OriginateDirection
? spec.getAttributes()
: findLastExistedBranch().getAttributes();
- final BranchElement branch =
+ final BranchElement newBranch =
(BranchElement)createBranchElement(current.element,
attrs);
- final ChangeDesc change = new ChangeDesc(branch, true);
- int index = lastBranch.getElementIndex(offset);
- if (lastBranch.getElement(index).getEndOffset() <= offset) {
- ++index;
- }
- // Now copy all elements from lastBranch to the new one
- final List children = new ArrayList();
- final int count = lastBranch.getElementCount();
- for (int i = index; i < count; i++) {
- children.add(clone(branch, lastBranch.getElement(i)));
+
+ final ChangeDesc lastChange = (ChangeDesc)changes.get(changes.size() - 1);
+ int startIndex = lastChange.getChildIndexAtOffset(offset);
+ if (lastChange.getChildElement(startIndex).getEndOffset() <= offset) {
+ ++startIndex;
+ }
+ moveChildren(newBranch, lastChange, startIndex);
+
+ current.added.add(newBranch);
+ if (current.getChildIndex() == -1) {
+ int newIndex = current.getChildIndexAtOffset(offset);
+ if (newBranch.getElementCount() > 0
+ && newBranch.getEndOffset()
+ > current.getChildElement(newIndex).getStartOffset()) {
+ ++newIndex;
+ }
+ current.setChildIndex(newIndex);
+ }
+ if (current.isApplied()) {
+ int replaceIndex = current.getChildIndexAtOffset(offset);
+ if (newBranch.getElementCount() > 0
+ && newBranch.getEndOffset()
+ > current.getChildElement(replaceIndex).getStartOffset()) {
+ ++replaceIndex;
+ }
+ current.element.replace(replaceIndex, 0,
+ new Element[] {newBranch});
+ } else {
+ current.apply();
+ }
+
+ current = new ChangeDesc(newBranch, true);
+ changeStack.push(current);
+ }
+
+ private void moveChildren(final BranchElement newParent,
+ final ChangeDesc sourceDesc,
+ final int startIndex) {
+ // copy all elements from lastBranch to the new one
+ final int count = sourceDesc.element.getElementCount();
+ final Element[] children = new Element[count - startIndex];
+ for (int i = startIndex; i < count; i++) {
+ children[i - startIndex] = clone(newParent, sourceDesc.getChildElement(i));
}
// Now we need to remove all previously added elements which were
// copied from added list
- for (int i = index - lastChange.index, j = index; j < count; j++) {
-
- final Object addedElement =
- i > 0 && i < lastChange.added.size()
- ? lastChange.added.get(i)
- : null;
- final Object existingElement = lastBranch.getElement(j);
+ final int i = startIndex - sourceDesc.getChildIndex();
+ for (int j = startIndex; j < count; j++) {
+ final Object addedElement = sourceDesc.getAddedElement(i);
+ final Object existingElement = sourceDesc.getChildElement(j);
if (addedElement == existingElement) {
- lastChange.added.remove(addedElement);
- } else if (!lastChange.justCreated) {
- lastChange.removed.add(existingElement);
+ sourceDesc.added.remove(addedElement);
+ } else if (!sourceDesc.justCreated) {
+ sourceDesc.removed.add(existingElement);
}
}
- // Complete the removal of elements from last branch
- if (count - index > 0) {
- lastBranch.replace(index, count - index, new Element[0]);
- }
-
- // Place copied children into the new element
- branch.replace(0, 0,
- (Element[])children.toArray(new Element[children.size()]));
- //change.setIndex(0);
- //change.added.addAll(children);
- //change.apply();
-
- current.added.add(branch);
- if (current.index == -1) {
- current.index = current.element.getElementIndex(offset);
- if (branch.getElementCount() > 0
- && branch.getEndOffset()
- > current.element.getElement(current.index)
- .getStartOffset()) {
- ++current.index;
- }
- }
- if (!current.isApplied()) {
- current.apply();
- } else {
- int replaceIndex = current.element.getElementIndex(offset);
- if (branch.getElementCount() > 0
- && branch.getEndOffset()
- > current.element
- .getElement(replaceIndex).getStartOffset()) {
- ++replaceIndex;
- }
- current.element.replace(replaceIndex, 0,
- new Element[] {branch});
+ // Complete the removal of elements from source
+ if (count - startIndex > 0) {
+ sourceDesc.element.replace(startIndex, count - startIndex, new Element[0]);
}
- current = change;
- changeStack.push(current);
+ // Place copied children into the new parent
+ newParent.replace(0, 0, children);
}
private void insertStartOriginate(final ElementSpec spec) {
- if (!create) {
+ if (current == null) {
+ insertStartJoinPrevious(spec);
+ } else if (!create && !changes.isEmpty()) {
insertStartFracture(spec);
- } else if (current == null) {
- insertStartJoinPrevious();
} else {
Element branch = createBranchElement(current.element,
spec.getAttributes());
- if (current.getIndex() < 0) {
- current.setIndex(current.element.getElementIndex(offset));
- }
+ current.setChildIndexByOffset(offset);
current.added.add(branch);
current = new ChangeDesc(branch, true);
changeStack.push(current);
@@ -622,53 +577,61 @@
}
private void insertStartJoinNext(final ElementSpec spec) {
- final int index = current.element.getElementIndex(offset);
- current = new ChangeDesc(current.element.getElement(index));
+ current = new ChangeDesc(current.getChildAtOffset(offset));
changeStack.push(current);
}
- private void insertStartJoinPrevious() {
+ private void insertStartJoinPrevious(final ElementSpec spec) {
if (current == null) {
current = new ChangeDesc(getRootElement());
+ // TODO are old attributes to be removed?
+ final AttributeSet specAttr = spec.getAttributes();
+ if (specAttr != null) {
+ ((AbstractElement)getRootElement()).addAttributes(specAttr);
+ }
changeStack.push(current);
} else {
- final int index = current.element.getElementIndex(offset);
- current = new ChangeDesc(current.element.getElement(index));
+ current = new ChangeDesc(current.getChildAtOffset(offset));
changeStack.push(current);
}
}
private void insertEndTag() {
- if (current.removed.size() == 0 && current.added.size() == 0) {
- current.setIndex(current.element.getElementIndex(offset));
- Element leaf = current.element.getElement(current.getIndex());
+ if (current.isEmpty()) {
+ current.setChildIndexByOffset(offset);
+ Element leaf = current.getCurrentChild();
final int start = leaf.getStartOffset();
final int end = leaf.getEndOffset();
if (start < offset && offset < end
|| start < offset + length && offset + length < end) {
- current.removed.add(leaf);
-
- if (leaf.getStartOffset() < offset) {
- current.added.add(
- createLeafElement(current.element,
- leaf.getAttributes(),
- leaf.getStartOffset(),
- offset));
- }
- if (offset + length < leaf.getEndOffset()) {
- current.added.add(
- createLeafElement(current.element,
- leaf.getAttributes(),
- offset + length,
- leaf.getEndOffset()));
+ if (leaf.isLeaf()) {
+ current.splitLeafElement(leaf, offset, offset + length, false, null);
+ } else if (length != 0) {
+ BranchElement rightBranch = splitBranch(leaf);
+ current.added.add(rightBranch);
+ int newIndex = current.getChildIndexAtOffset(offset + length);
+ if (rightBranch.getElementCount() > 0
+ && rightBranch.getEndOffset()
+ > current.getChildElement(newIndex).getStartOffset()) {
+ ++newIndex;
+ }
+ current.childIndex = newIndex;
}
}
}
leaveParagraph();
changes.add(current);
changeStack.pop();
- current = (ChangeDesc)changeStack.peek();
+ current = changeStack.empty() ? null : (ChangeDesc)changeStack.peek();
+ }
+
+ private BranchElement splitBranch(final Element branch) {
+ BranchElement result = current.createBranchElement(branch.getAttributes());
+ final ChangeDesc lastChange = (ChangeDesc)changes.get(changes.size() - 1);
+ int startIndex = lastChange.getChildIndexAtOffset(offset + length);
+ moveChildren(result, lastChange, startIndex);
+ return result;
}
private BranchElement findLastExistedBranch() {
@@ -681,35 +644,19 @@
}
private void leaveParagraph() {
- if ((current.removed.size() == 0 && current.added.size() == 0)) {
+ if (current == null || current.isEmpty()) {
return;
}
- if (current.removed.size() > 0
- && offset < ((Element)current.removed.get(current.removed.size()
- - 1)).getEndOffset()
- && !(current.added.size() > 0
- && offset < ((Element)current.added
- .get(current.added.size() - 1))
- .getEndOffset())) {
- final Element leaf = current.element
- .getElement(current.getIndex());
- if (event.getOffset() + event.getLength()
- < leaf.getEndOffset()) {
-
- current.added.add(createLeafElement(current.element,
- leaf.getAttributes(),
- event.getOffset()
- + event.getLength(),
- leaf.getEndOffset()));
- }
+ if (tail != null) {
+ current.added.add(tail);
}
+ tail = null;
current.apply();
}
private Element[] listToElementArray(final List list) {
- Element[] result = new Element[list.size()];
- return (Element[])list.toArray(result);
+ return (Element[])list.toArray(new Element[list.size()]);
}
private void initChangeLists() {
@@ -725,8 +672,10 @@
this.changes.clear();
this.changeStack.clear();
+ this.current = null;
this.create = false;
+ this.tail = null;
}
private void readObject(final ObjectInputStream ois)
@@ -875,9 +824,9 @@
}
}
- private static final class ChangeDesc {
+ private final class ChangeDesc {
public final BranchElement element;
- private int index = -1;
+ private int childIndex = -1;
public final List added = new ArrayList();
public final List removed = new ArrayList();
public final boolean justCreated;
@@ -893,30 +842,32 @@
this.justCreated = justCreated;
}
- public void setIndex(final int index) {
- if (this.index != -1) {
- throw new Error("Index has already been set, "
- + "and cannot be changed.");
+ public ChangeDesc(final Element element,
+ final int offset) {
+ this(element, false);
+ setChildIndexByOffset(offset);
+ }
+
+ public void setChildIndex(final int index) {
+ if (this.childIndex == -1) {
+ this.childIndex = index;
}
- this.index = index;
}
- public int getIndex() {
- return index;
+ public int getChildIndex() {
+ return childIndex;
}
public Element[] getChildrenAdded() {
- final Element[] result = new Element[added.size()];
- return (Element[])added.toArray(result);
+ return (Element[])added.toArray(new Element[added.size()]);
}
public Element[] getChildrenRemoved() {
- final Element[] result = new Element[removed.size()];
- return (Element[])removed.toArray(result);
+ return (Element[])removed.toArray(new Element[removed.size()]);
}
public ElementEdit toElementEdit() {
- return new ElementEdit(element, index,
+ return new ElementEdit(element, childIndex,
getChildrenRemoved(),
getChildrenAdded());
}
@@ -925,12 +876,12 @@
if (applied || isEmpty()) {
return;
}
- if (index == -1) {
- throw new Error("Index is not initialized");
+ if (childIndex == -1) {
+ childIndex = 0;
}
applied = true;
- element.replace(index, removed.size(), getChildrenAdded());
+ element.replace(childIndex, removed.size(), getChildrenAdded());
}
public boolean isEmpty() {
@@ -940,6 +891,84 @@
public boolean isApplied() {
return applied;
}
+
+ public void createLeafElement(final AttributeSet attr, final int start,
+ final int end) {
+ added.add(DefaultStyledDocument.this.createLeafElement(element, attr, start, end));
+ }
+
+ public BranchElement createBranchElement(final AttributeSet attr) {
+ return (BranchElement)DefaultStyledDocument.this.createBranchElement(element, attr);
+ }
+
+ public void splitLeafElement(final Element leaf, final int splitOffset) {
+ final AttributeSet attrs = leaf.getAttributes();
+ createLeafElement(attrs , leaf.getStartOffset(), splitOffset);
+ createLeafElement(attrs, splitOffset, leaf.getEndOffset());
+ removed.add(leaf);
+ }
+
+ public void splitLeafElement(final Element child,
+ final int splitOffset1,
+ final int splitOffset2,
+ final boolean createMiddle,
+ final AttributeSet middleAttr) {
+ splitLeafElement(child, splitOffset1, splitOffset2, splitOffset2, createMiddle, middleAttr);
+ }
+
+ public void splitLeafElement(final Element child,
+ final int splitOffset1,
+ final int splitOffset2,
+ final int splitOffset3,
+ final boolean createMiddle,
+ final AttributeSet middleAttr) {
+ final AttributeSet attrs = child.getAttributes();
+ if (child.getStartOffset() < splitOffset1) {
+ createLeafElement(attrs, child.getStartOffset(), splitOffset1);
+ }
+ if (createMiddle) {
+ createLeafElement(middleAttr, splitOffset1, splitOffset2);
+ }
+ if (splitOffset3 < child.getEndOffset()) {
+ createLeafElement(attrs, splitOffset3, child.getEndOffset());
+ }
+ removed.add(child);
+ }
+
+ public void setChildIndexByOffset(final int offset) {
+ setChildIndex(element.getElementIndex(offset));
+ }
+
+ public Element getChildAtOffset(final int offset) {
+ return element.getElement(element.getElementIndex(offset));
+ }
+
+ public int getChildIndexAtOffset(final int offset) {
+ return element.getElementIndex(offset);
+ }
+
+ public Element getCurrentChild() {
+ return element.getElement(childIndex);
+ }
+
+ public Element getChildElement(final int index) {
+ return element.getElement(index);
+ }
+
+ public void removeChildElement(final int index) {
+ removed.add(element.getElement(index));
+ }
+
+ public Element getAddedElement(final int i) {
+ return (i > 0 && i < added.size()) ? (Element)added.get(i) : null;
+ }
+
+ public Element getLastAddedElement() {
+ return (Element)added.get(added.size() - 1);
+ }
+ public Element getLastRemovedElement() {
+ return (Element)removed.get(removed.size() - 1);
+ }
}
public static final int BUFFER_SIZE_DEFAULT = 4096;
@@ -1004,8 +1033,13 @@
}
public Element getParagraphElement(final int offset) {
- Element root = getDefaultRootElement();
- return root.getElement(root.getElementIndex(offset));
+ Element branch;
+ Element child = getDefaultRootElement();
+ do {
+ branch = child;
+ child = branch.getElement(branch.getElementIndex(offset));
+ } while (!child.isLeaf());
+ return branch;
}
public void setCharacterAttributes(final int offset,
@@ -1132,13 +1166,7 @@
}
protected void create(final ElementSpec[] specs) {
- final StringBuffer text = new StringBuffer();
- for (int i = 0; i < specs.length; i++) {
- if (specs[i].getLength() > 0) {
- text.append(specs[i].getArray(), specs[i].getOffset(),
- specs[i].getLength());
- }
- }
+ final StringBuffer text = appendSpecsText(specs);
writeLock();
try {
@@ -1188,13 +1216,7 @@
protected void insert(final int offset, final ElementSpec[] specs)
throws BadLocationException {
- final StringBuffer text = new StringBuffer();
- for (int i = 0; i < specs.length; i++) {
- if (specs[i].getLength() > 0) {
- text.append(specs[i].getArray(), specs[i].getOffset(),
- specs[i].getLength());
- }
- }
+ final StringBuffer text = appendSpecsText(specs);
writeLock();
try {
UndoableEdit contentInsert =
@@ -1246,15 +1268,15 @@
final boolean hasLineBreak = firstBreak != -1;
Element charElem = getCharacterElement(offset);
- ElementSpec spec;
+ ElementSpec spec = null;
if (!hasLineBreak) {
if (splitPrevParagraph) {
- specs.add(new ElementSpec(null, ElementSpec.EndTagType));
-
- spec = new ElementSpec(defaultLogicalStyle,
- ElementSpec.StartTagType);
- spec.setDirection(ElementSpec.JoinNextDirection);
- specs.add(spec);
+ splitBranch(specs, offset, length, charElem,
+ ElementSpec.JoinNextDirection);
+ // The direction of the next Content element must be chosen
+ // based on attributes of the first Content element
+ // in the next paragraph
+ charElem = getCharacterElement(offset + length);
}
spec = new ElementSpec(attributes, ElementSpec.ContentType, length);
if (charElem.getAttributes().isEqual(attributes)) {
@@ -1269,10 +1291,8 @@
int processedLength = 0;
if (splitPrevParagraph) {
- specs.add(new ElementSpec(null, ElementSpec.EndTagType));
-
- specs.add(new ElementSpec(defaultLogicalStyle,
- ElementSpec.StartTagType));
+ splitBranch(specs, offset, length, charElem,
+ ElementSpec.OriginateDirection);
}
while (currentOffset < offset + length) {
@@ -1322,11 +1342,47 @@
super.insertUpdate(event, attrs);
}
+ private void splitBranch(final List specs,
+ final int offset, final int length,
+ final Element leaf,
+ final short lastSpecDirection) {
+ ElementSpec spec = null;
+ Element branch = leaf.getParentElement();
+ final int endOffset = offset + length;
+ while (branch != null && branch.getEndOffset() == endOffset) {
+ specs.add(new ElementSpec(null, ElementSpec.EndTagType));
+ branch = branch.getParentElement();
+ }
+
+ branch = branch.getElement(branch.getElementIndex(offset) + 1);
+ while (branch != null
+ && !branch.isLeaf()
+ && branch.getStartOffset() == endOffset) {
+ spec = new ElementSpec(branch.getAttributes(),
+ ElementSpec.StartTagType);
+ spec.setDirection(ElementSpec.JoinNextDirection);
+ specs.add(spec);
+ branch = branch.getElement(0);
+ }
+ spec.setDirection(lastSpecDirection);
+ }
+
protected void removeUpdate(final DefaultDocumentEvent event) {
buffer.remove(event.getOffset(), event.getLength(), event);
}
protected void styleChanged(final Style style) {
+ }
+
+ private StringBuffer appendSpecsText(final ElementSpec[] specs) {
+ final StringBuffer result = new StringBuffer();
+ for (int i = 0; i < specs.length; i++) {
+ if (specs[i].getLength() > 0) {
+ result.append(specs[i].getArray(), specs[i].getOffset(),
+ specs[i].getLength());
+ }
+ }
+ return result;
}
private void addListenerToStyles() {
Modified: incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/FlowView.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/FlowView.java?rev=427121&r1=427120&r2=427121&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/FlowView.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/FlowView.java Mon Jul 31 07:08:47 2006
@@ -30,6 +30,8 @@
public abstract class FlowView extends BoxView {
public static class FlowStrategy {
+ private static FlowStrategy sharedStrategy;
+
public void insertUpdate(final FlowView fv,
final DocumentEvent event,
final Rectangle alloc) {
@@ -127,12 +129,16 @@
span = (int)view.getPreferredSpan(flowAxis);
weight = view.getBreakWeight(flowAxis, offset, rowSpan);
if (weight >= ForcedBreakWeight) {
- view = view.breakView(flowAxis, offset, x, rowSpan);
+ final View broken = view.breakView(flowAxis, offset, x, rowSpan);
+ if (view == broken && row.getViewCount() > 0) {
+ break;
+ }
+ view = broken;
}
row.append(view);
offset = view.getEndOffset();
}
- } while (view != null && span < rowSpan
+ } while (view != null && span <= rowSpan
&& weight < ForcedBreakWeight);
if (span > rowSpan) {
@@ -163,6 +169,14 @@
return result;
}
+ static FlowStrategy getSharedStrategy() {
+ if (sharedStrategy == null) {
+ sharedStrategy = new FlowStrategy();
+ }
+
+ return sharedStrategy;
+ }
+
private void invalidateFlow(final FlowView fv,
final DocumentEvent event,
final Rectangle alloc) {
@@ -190,29 +204,12 @@
super(element);
}
- protected void childAllocation(final int index, final Rectangle rc) {
+ public int getResizeWeight(final int axis) {
+ return 1;
}
- protected View getViewAtPoint(final int x, final int y,
- final Rectangle alloc) {
- throw new UnsupportedOperationException("Not implemented");
- }
-
- protected int getViewIndexAtPosition(final int pos) {
- if (pos < getStartOffset() || pos >= getEndOffset()) {
- return -1;
- }
- return super.getViewIndexAtPosition(pos);
- }
-
- protected boolean isAfter(final int x, final int y,
- final Rectangle rc) {
- throw new UnsupportedOperationException("Not implemented");
- }
-
- protected boolean isBefore(final int x, final int y,
- final Rectangle rc) {
- throw new UnsupportedOperationException("Not implemented");
+ public float getMinimumSpan(final int axis) {
+ return 0;
}
public float getPreferredSpan(final int axis) {
@@ -229,8 +226,13 @@
return spanY;
}
+ public float getMaximumSpan(final int axis) {
+ return getPreferredSpan(axis);
+ }
+
public void paint(final Graphics g, final Shape shape) {
- throw new UnsupportedOperationException("Not implemented");
+ throw new UnsupportedOperationException("Not applicable to "
+ + "Layout Pool");
}
public void preferenceChanged(final View child,
@@ -245,6 +247,11 @@
super.preferenceChanged(child, width, height);
}
+ public AttributeSet getAttributes() {
+ final View parent = getParent();
+ return parent != null ? parent.getAttributes() : null;
+ }
+
protected void loadChildren(final ViewFactory factory) {
if (factory != null) {
super.loadChildren(factory);
@@ -259,6 +266,34 @@
super.forwardUpdateToView(view, event, shape, factory);
}
+ protected void childAllocation(final int index, final Rectangle rc) {
+ }
+
+ protected View getViewAtPoint(final int x, final int y,
+ final Rectangle alloc) {
+ throw new UnsupportedOperationException("Not applicable to "
+ + "Layout Pool");
+ }
+
+ protected int getViewIndexAtPosition(final int pos) {
+ if (pos < getStartOffset() || pos >= getEndOffset()) {
+ return -1;
+ }
+ return super.getViewIndexAtPosition(pos);
+ }
+
+ protected boolean isAfter(final int x, final int y,
+ final Rectangle rc) {
+ throw new UnsupportedOperationException("Not applicable to "
+ + "Layout Pool");
+ }
+
+ protected boolean isBefore(final int x, final int y,
+ final Rectangle rc) {
+ throw new UnsupportedOperationException("Not applicable to "
+ + "Layout Pool");
+ }
+
private float getSpanX() {
float span = 0;
for (int i = 0; i < getViewCount(); i++) {
@@ -279,7 +314,7 @@
protected View layoutPool;
protected int layoutSpan = Short.MAX_VALUE;
- protected FlowStrategy strategy = new FlowStrategy();
+ protected FlowStrategy strategy = FlowStrategy.getSharedStrategy();
public FlowView(final Element element, final int axis) {
super(element, axis);
@@ -317,17 +352,13 @@
strategy.changedUpdate(this, event, shapeToRect(alloc));
}
- public void setParent(final View parentView) {
- super.setParent(parentView);
- }
-
protected SizeRequirements
calculateMinorAxisRequirements(final int axis,
final SizeRequirements sr) {
SizeRequirements result = sr != null ? sr : new SizeRequirements();
result.minimum = (int)layoutPool.getMinimumSpan(axis);
result.preferred = (int)layoutPool.getPreferredSpan(axis);
- result.maximum = Short.MAX_VALUE;
+ result.maximum = Integer.MAX_VALUE;
result.alignment = ALIGN_CENTER;
return result;
}
Modified: incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/ParagraphView.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/ParagraphView.java?rev=427121&r1=427120&r2=427121&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/ParagraphView.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/ParagraphView.java Mon Jul 31 07:08:47 2006
@@ -56,6 +56,11 @@
return super.getEndOffset();
}
+ public AttributeSet getAttributes() {
+ final View parent = getParent();
+ return parent != null ? parent.getAttributes() : null;
+ }
+
protected void loadChildren(final ViewFactory factory) {
}
@@ -75,9 +80,6 @@
SizeRequirements result = baselineRequirements(axis, r);
lineSpace = (int)(result.preferred * lineSpacing);
- result.minimum += lineSpace;
- result.preferred += lineSpace;
- result.maximum = result.preferred;
return result;
}
Modified: incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/View.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/View.java?rev=427121&r1=427120&r2=427121&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/View.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/View.java Mon Jul 31 07:08:47 2006
@@ -205,7 +205,9 @@
}
final View view = getView(index);
- return view != null ? view.getToolTipText(x, y, shape) : null;
+ return view != null
+ ? view.getToolTipText(x, y, getChildAllocation(index, shape))
+ : null;
}
public View getView(final int index) {
@@ -221,9 +223,14 @@
}
public int getViewIndex(final float x, final float y, final Shape shape) {
+ if (shape == null) {
+ return -1;
+ }
+
final int count = getViewCount();
for (int i = 0; i < count; i++) {
- if (getChildAllocation(i, shape).contains(x, y)) {
+ final Shape childAllocation = getChildAllocation(i, shape);
+ if (childAllocation != null && childAllocation.contains(x, y)) {
return i;
}
}
Added: incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/BRView.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/BRView.java?rev=427121&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/BRView.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/BRView.java Mon Jul 31 07:08:47 2006
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2005 - 2006 The Apache Software Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @author Vadim L. Bogdanov
+ * @version $Revision$
+ */
+package javax.swing.text.html;
+
+import javax.swing.text.Element;
+
+class BRView extends InlineView {
+ BRView(final Element elem) {
+ super(elem);
+ }
+
+ public int getBreakWeight(final int axis, final float pos, final float len) {
+ return ForcedBreakWeight;
+ }
+}
Added: incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/BackgroundImageLoader.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/BackgroundImageLoader.java?rev=427121&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/BackgroundImageLoader.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/BackgroundImageLoader.java Mon Jul 31 07:08:47 2006
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2005 - 2006 The Apache Software Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @author Alexey A. Ivanov
+ * @version $Revision$
+ */
+package javax.swing.text.html;
+
+import java.awt.Image;
+import java.awt.Toolkit;
+import java.awt.image.ImageObserver;
+import java.net.URL;
+
+/**
+ * Loads an image asynchronously, that is in another thread.
+ */
+class BackgroundImageLoader implements ImageObserver {
+ final int desiredWidth;
+ final int desiredHeight;
+
+ final Image image;
+
+ private int imageWidth = -1;
+ private int imageHeight = -1;
+
+ private volatile boolean ready;
+ private volatile boolean error;
+
+ BackgroundImageLoader(final URL url,
+ final int desiredWidth, final int desiredHeight) {
+ this.desiredWidth = desiredWidth;
+ this.desiredHeight = desiredHeight;
+
+ error = url == null;
+ if (!error) {
+ final Toolkit tk = Toolkit.getDefaultToolkit();
+ image = tk.createImage(url);
+ tk.prepareImage(image, desiredWidth, desiredHeight, this);
+ } else {
+ image = null;
+ }
+ }
+
+ public boolean imageUpdate(final Image image, final int flags,
+ final int x, final int y,
+ final int width, final int height) {
+ if ((flags & WIDTH) != 0) {
+ imageWidth = desiredWidth == -1 ? width : desiredWidth;
+ }
+ if ((flags & HEIGHT) != 0) {
+ imageHeight = desiredHeight == -1 ? height : desiredHeight;
+ }
+ if ((flags & ALLBITS) != 0) {
+ ready = true;
+ onReady();
+ }
+ if ((flags & (ERROR | ABORT)) != 0) {
+ error = true;
+ onError();
+ return false;
+ }
+ return width == -1 || height == -1 || !ready;
+ }
+
+ public final Image getImage() {
+ return image;
+ }
+
+ public final int getWidth() {
+ return imageWidth;
+ }
+
+ public final int getHeight() {
+ return imageHeight;
+ }
+
+ public final boolean isReady() {
+ return ready;
+ }
+
+ public final boolean isError() {
+ return error;
+ }
+
+ public final void waitForImage() {
+ while (!ready && !error) {
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ protected void onReady() {
+ }
+
+ protected void onError() {
+ }
+}
\ No newline at end of file
Added: incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/BlockView.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/BlockView.java?rev=427121&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/BlockView.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/BlockView.java Mon Jul 31 07:08:47 2006
@@ -0,0 +1,159 @@
+/*
+ * Copyright 2005 - 2006 The Apache Software Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @author Alexey A. Ivanov
+ * @version $Revision$
+ */
+package javax.swing.text.html;
+
+import java.awt.Graphics;
+import java.awt.Rectangle;
+import java.awt.Shape;
+
+import javax.swing.SizeRequirements;
+import javax.swing.event.DocumentEvent;
+import javax.swing.text.AttributeSet;
+import javax.swing.text.BoxView;
+import javax.swing.text.Element;
+import javax.swing.text.View;
+import javax.swing.text.ViewFactory;
+import javax.swing.text.html.StyleSheet.BoxPainter;
+
+public class BlockView extends BoxView {
+ private AttributeSet attrs;
+ private BoxPainter boxPainter;
+
+ private CSS.Length width;
+ private CSS.Length height;
+ private float effectiveWidth;
+ private float effectiveHeight;
+
+ public BlockView(final Element elem, final int axis) {
+ super(elem, axis);
+ }
+
+ public float getAlignment(final int axis) {
+ return 0;
+ }
+
+ public AttributeSet getAttributes() {
+ if (attrs == null) {
+ attrs = getStyleSheet().getViewAttributes(this);
+ }
+ return attrs;
+ }
+
+ public void setParent(final View parent) {
+ super.setParent(parent);
+ if (parent != null) {
+ setPropertiesFromAttributes();
+ }
+ }
+
+ public void changedUpdate(final DocumentEvent event,
+ final Shape shape,
+ final ViewFactory factory) {
+ attrs = getStyleSheet().getViewAttributes(this);
+ setPropertiesFromAttributes();
+ super.changedUpdate(event, shape, factory);
+ }
+
+ public void paint(final Graphics g, final Shape allocation) {
+ Rectangle rc = allocation.getBounds();
+ boxPainter.paint(g, rc.x, rc.y, rc.width, rc.height, this);
+ super.paint(g, allocation);
+ }
+
+ public void setSize(final float width, final float height) {
+ boolean widthChanged = effectiveWidth != calculateEffectiveSize(X_AXIS);
+ boolean heightChanged = effectiveHeight
+ != calculateEffectiveSize(Y_AXIS);
+ if (widthChanged || heightChanged) {
+ preferenceChanged(this, widthChanged, heightChanged);
+ return;
+ }
+ super.setSize(width, height);
+ }
+
+ protected SizeRequirements
+ calculateMajorAxisRequirements(final int axis,
+ final SizeRequirements r) {
+
+ SizeRequirements result = super.calculateMajorAxisRequirements(axis, r);
+ float size = calculateEffectiveSize(axis);
+ if (size - getFullInsets(axis) > result.minimum) {
+ result.minimum = (int)size - getFullInsets(axis);
+ result.preferred = result.minimum;
+ result.maximum = result.minimum;
+ }
+ return result;
+ }
+
+ protected SizeRequirements
+ calculateMinorAxisRequirements(final int axis,
+ final SizeRequirements r) {
+
+ SizeRequirements result = super.calculateMinorAxisRequirements(axis, r);
+ float size = calculateEffectiveSize(axis);
+ if (size - getFullInsets(axis) > result.minimum) {
+ result.minimum = (int)size - getFullInsets(axis);
+ result.preferred = result.minimum;
+ result.maximum = result.minimum;
+ }
+ return result;
+ }
+
+ protected StyleSheet getStyleSheet() {
+ return ((HTMLDocument)getDocument()).getStyleSheet();
+ }
+
+ protected void setPropertiesFromAttributes() {
+ boxPainter = getStyleSheet().getBoxPainter(getAttributes());
+ boxPainter.setView(this);
+ setInsets((short)boxPainter.getInset(TOP, this),
+ (short)boxPainter.getInset(LEFT, this),
+ (short)boxPainter.getInset(BOTTOM, this),
+ (short)boxPainter.getInset(RIGHT, this));
+ width = getSizeAttribute(X_AXIS);
+ height = getSizeAttribute(Y_AXIS);
+ }
+
+ private float calculateEffectiveSize(final int axis) {
+ if (axis == X_AXIS) {
+ effectiveWidth = calculateEffectiveSize(width);
+ return effectiveWidth;
+ } else {
+ effectiveHeight = calculateEffectiveSize(height);
+ return effectiveHeight;
+ }
+ }
+
+ private float calculateEffectiveSize(final CSS.Length size) {
+ return size != null ? size.floatValue(this) : 0;
+ }
+
+ private CSS.Length getSizeAttribute(final int axis) {
+ return (CSS.Length)getAttributes().getAttribute(axis == X_AXIS
+ ? CSS.Attribute.WIDTH
+ : CSS.Attribute.HEIGHT);
+ }
+
+ private int getFullInsets(final int axis) {
+ return axis == X_AXIS ? getLeftInset() + getRightInset()
+ : getTopInset() + getBottomInset();
+ }
+}
+