http://blog.fyent.net/2011/01/java_swing_merge_styleddocument/
public void mergeDocument(DefaultStyledDocument source,
DefaultStyledDocument dest) throws BadLocationException {
ArrayList specs = new ArrayList();
DefaultStyledDocument.ElementSpec spec = new DefaultStyledDocument.ElementSpec(
new SimpleAttributeSet(),
DefaultStyledDocument.ElementSpec.EndTagType);
specs.add(spec);
fillSpecs(source.getDefaultRootElement(), specs, false);
spec = new DefaultStyledDocument.ElementSpec(new SimpleAttributeSet(),
DefaultStyledDocument.ElementSpec.StartTagType);
specs.add(spec);
DefaultStyledDocument.ElementSpec[] arr = new DefaultStyledDocument.ElementSpec[specs
.size()];
specs.toArray(arr);
insertSpecs(dest, dest.getLength(), arr);
}
protected void insertSpecs(DefaultStyledDocument doc, int offset,
DefaultStyledDocument.ElementSpec[] specs) {
try {
// doc.insert(0, specs); method is protected so we have to
// extend document or use such a hack
Method m = DefaultStyledDocument.class.getDeclaredMethod("insert",
new Class[] { int.class,
DefaultStyledDocument.ElementSpec[].class });
m.setAccessible(true);
m.invoke(doc, new Object[] { offset, specs });
} catch (Exception e) {
e.printStackTrace();
}
}
protected void fillSpecs(Element elem, ArrayList specs, boolean includeRoot)
throws BadLocationException {
DefaultStyledDocument.ElementSpec spec;
if (elem.isLeaf()) {
String str = elem.getDocument().getText(elem.getStartOffset(),
elem.getEndOffset() - elem.getStartOffset());
spec = new DefaultStyledDocument.ElementSpec(elem.getAttributes(),
DefaultStyledDocument.ElementSpec.ContentType, str
.toCharArray(), 0, str.length());
specs.add(spec);
} else {
if (includeRoot) {
spec = new DefaultStyledDocument.ElementSpec(elem
.getAttributes(),
DefaultStyledDocument.ElementSpec.StartTagType);
specs.add(spec);
}
for (int i = 0; i < elem.getElementCount(); i++) {
fillSpecs(elem.getElement(i), specs, true);
}
if (includeRoot) {
spec = new DefaultStyledDocument.ElementSpec(elem
.getAttributes(),
DefaultStyledDocument.ElementSpec.EndTagType);
specs.add(spec);
}
}
}
DefaultStyledDocument dest) throws BadLocationException {
ArrayList specs = new ArrayList();
DefaultStyledDocument.ElementSpec spec = new DefaultStyledDocument.ElementSpec(
new SimpleAttributeSet(),
DefaultStyledDocument.ElementSpec.EndTagType);
specs.add(spec);
fillSpecs(source.getDefaultRootElement(), specs, false);
spec = new DefaultStyledDocument.ElementSpec(new SimpleAttributeSet(),
DefaultStyledDocument.ElementSpec.StartTagType);
specs.add(spec);
DefaultStyledDocument.ElementSpec[] arr = new DefaultStyledDocument.ElementSpec[specs
.size()];
specs.toArray(arr);
insertSpecs(dest, dest.getLength(), arr);
}
protected void insertSpecs(DefaultStyledDocument doc, int offset,
DefaultStyledDocument.ElementSpec[] specs) {
try {
// doc.insert(0, specs); method is protected so we have to
// extend document or use such a hack
Method m = DefaultStyledDocument.class.getDeclaredMethod("insert",
new Class[] { int.class,
DefaultStyledDocument.ElementSpec[].class });
m.setAccessible(true);
m.invoke(doc, new Object[] { offset, specs });
} catch (Exception e) {
e.printStackTrace();
}
}
protected void fillSpecs(Element elem, ArrayList specs, boolean includeRoot)
throws BadLocationException {
DefaultStyledDocument.ElementSpec spec;
if (elem.isLeaf()) {
String str = elem.getDocument().getText(elem.getStartOffset(),
elem.getEndOffset() - elem.getStartOffset());
spec = new DefaultStyledDocument.ElementSpec(elem.getAttributes(),
DefaultStyledDocument.ElementSpec.ContentType, str
.toCharArray(), 0, str.length());
specs.add(spec);
} else {
if (includeRoot) {
spec = new DefaultStyledDocument.ElementSpec(elem
.getAttributes(),
DefaultStyledDocument.ElementSpec.StartTagType);
specs.add(spec);
}
for (int i = 0; i < elem.getElementCount(); i++) {
fillSpecs(elem.getElement(i), specs, true);
}
if (includeRoot) {
spec = new DefaultStyledDocument.ElementSpec(elem
.getAttributes(),
DefaultStyledDocument.ElementSpec.EndTagType);
specs.add(spec);
}
}
}