OK, so the simplest approach was to extend JTextPane. The extended class created and managed the underlying list. On format change (eg new colours) the list completely reformats the data. The only real problem was that the auto-scrolling is not 100% reliable, Both:
Container parent = getParent();
// get the parent until scroll pane is found
while (parent != null && !(parent instanceof JScrollPane)) {
parent = parent.getParent();
}
if (parent != null) {
JScrollPane scrollPane = (JScrollPane)parent;
scrollPane.getVerticalScrollBar().setValue(scrollPane.getVerticalScrollBar().getMaximum());
}
and
scrollRectToVisible(new Rectangle(0, getHeight() - 2, 1, 1));
Provide inconsistent results with the text pane sometimes not scrolling all the way.