I can do a simple test What i do is extend DefaultStyledDocument so i can override the method using reflection. Here is the code:
@Override public void insert(int offset, ElementSpec[] data) throws BadLocationException { if (offset > getLength() || offset < 0) { throw new BadLocationException("Invalid insert", offset); } if (data == null || data.length == 0) { return; } writeLock(); try { Content content = getContent(); //since instead of doing normal string insert we are going to use the gapvector directly, we don't do this //UndoableEdit cEdit = content.insertString(offset, sb.toString()); int charArraysSize = 0; int index = offset; for (ElementSpec e : data) { if (e.getLength() > 0) { charArraysSize += e.getLength(); bulkArgs[0] = index; bulkArgs[1] = e.getOffset(); bulkArgs[2] = e.getArray(); bulkArgs[3] = e.getLength(); index += e.getLength(); try { replace.invoke(content, bulkArgs); } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) { throw new AssertionError(ex); } } } if (charArraysSize == 0) { return; } //created the undoable edit corresponding to the whole inserted string //this can't be created because it is package protected in gapvector //UndoableEdit cEdit = new InsertUndo(offset, charArraysSize); DefaultDocumentEvent evnt = new DefaultDocumentEvent(offset, charArraysSize, DocumentEvent.EventType.INSERT); //evnt.addEdit(cEdit); buffer.insert(offset, charArraysSize, data, evnt); // update bidi (possibly) super.insertUpdate(evnt, null); // notify the listeners evnt.end(); fireInsertUpdate(evnt); fireUndoableEditUpdate(new UndoableEditEvent(this, evnt)); } finally { writeUnlock(); } } As you can see, i can't use undo-redo in this operation because the undoable edit i need to create is package protected in GapContent - it's a consequence of inlining the insertString function - but only for me, since this change in DefaultStyledDocument would compile. Obviously, the use of reflection would have to be replaced by a extension method, and this method is mostly worthwhile if you have a buffered builder that collects the ElementSpec's so as to insert them in bursts. I have such a builder, and it would be nice to use them in the test to simplify the building code. Can i use it?