/** * Whenever an UndoableEdit happens the edit will either be absorbed by the current compound edit * or a new compound edit will be started */ @Override public void undoableEditHappened(UndoableEditEvent e) { // Start a new compound edit AbstractDocument.DefaultDocumentEvent docEvt = (DefaultDocumentEvent) e.getEdit(); if (compoundEdit == null) { compoundEdit = startCompoundEdit(e.getEdit()); startCombine = false; updateDirty(); return; } int editLine = ((SyntaxDocument) docEvt.getDocument()).getLineNumberAt(docEvt.getOffset()); // Check for an incremental edit or backspace. // The Change in Caret position and Document length should both be // either 1 or -1. if ((startCombine || Math.abs(docEvt.getLength()) == 1) && editLine == lastLine) { compoundEdit.addEdit(e.getEdit()); startCombine = false; updateDirty(); return; } // Not incremental edit, end previous edit and start a new one lastLine = editLine; compoundEdit.end(); compoundEdit = startCompoundEdit(e.getEdit()); updateDirty(); }
@Override public void undo() throws CannotUndoException { // End the edit so future edits don't get absorbed by this edit if (compoundEdit != null) { compoundEdit.end(); } super.undo(); // Always start a new compound edit after an undo compoundEdit = null; }
/* ** Each CompoundEdit will store a group of related incremental edits ** (ie. each character typed or backspaced is an incremental edit) */ private CompoundEdit startCompoundEdit(UndoableEdit anEdit) { // Track Caret and Document information of this compound edit // AbstractDocument.DefaultDocumentEvent docEvt = (DefaultDocumentEvent) anEdit; // The compound edit is used to store incremental edits compoundEdit = new MyCompoundEdit(); compoundEdit.addEdit(anEdit); // The compound edit is added to the UndoManager. All incremental // edits stored in the compound edit will be undone/redone at once addEdit(compoundEdit); return compoundEdit; }