[jdom-interest] More on re-ordering elements: grandParent adopting child
Thomas Nichols
thomas.nichols at iname.com
Thu May 17 14:42:16 PDT 2001
Thanks to all who responded to earlier query (off list) -- I had not
understood that the PartialList returned by getContent is a "live" subList
of content, this is very elegant.
However, I still have a problem with the code below. This (I think!) takes
a child element oldChild and replaces it with a newChild, keeping the same
sequence within the parent. This quite simple task is proving difficult to
implement in JDOM.
The problem with the implementation below is thatPartialList.remove (Object
o) resets the 'parent' link, so that children.addContent ((Element) o)
throws NoSuchElementException.
From PartialList.java:
public boolean remove(Object o) {
backingList.remove(o);
if (o instanceof Element) {
((Element)o).setParent(null);
}
return super.remove(o);
}
The failing code:
void replaceChild (Element parent, Element oldChild, Element newChild) {
if (parent == null || oldChild == null)
return;
List children = parent.getChildren();
int oldIndex = children.indexOf (oldChild);
if (oldIndex != -1) {
// Make sure newChild is an orphan, so that it can be adopted:
if (newChild != null && newChild.getParent() != null)
newChild.getParent().removeContent (newChild);
// Now replace the child, using Element methods to ensure setParent()
is called correctly:
parent.removeContent (oldChild);
parent.addContent (newChild); // Will be appended.
newChild.parent == parent.
// Now move newChild to the correct place in the list by directly
manipulating the List. First refresh the list of children:
children = parent.getChildren();
children.remove (newChild); // Chop it from the end... ###
Sets newChild.parent back to null!
children.add (oldIndex, newChild); // ...and insert at the original
position. ### throws NoSuchElementException.
}
}
====
One suggestion was to use
Comparator comp = new YourComparator();
List children = el.getMixedContent();
Collections.sort( children, comp );
This is a good idea for a general "sort" problem, but I'm not at all sure
how to write a Comparator to do the above.
The approach I'm currently pursuing is to empty the parent of all content,
then put it back in again replacing oldChild with newChild.- please let me
know if you have any better suggestions, performance is unimpressive.
To clarify: I want newChild to take the place of oldChild, so that it comes
in the same location in the tree. A simple solution is to add an "int
index" parameter to the addContent call, and pass this through to
List.add(...). Is this problem common enough to warrant it? (I've found
several similar queries in the archives).
Alternative solution: rather than adding a raft of addContent (int index
(Blah blah) methods, just add a setAddContentIndex (int index), which would
set the index for the next call of any flavour of addContent (resetting it
afterwards).
Of course if the *specific* problem I have here is seen as general enough,
we could have an Element.replaceContent() family. Not sure this is wise,
though.
Thanks for all and any help,
Regards,
Thomas.
More information about the jdom-interest
mailing list