下面列出了怎么用javax.swing.undo.CompoundEdit的API类实例代码及写法,或者点击链接到github查看源代码。
/**
* Similar to beginUpdate(), but this beings an *insignificant* edit--that is,
* an edit that won't be considered a "step" in the undo/redo list, but will be
* undone/redone when moving between significant steps.
*/
public synchronized void beginInsignificantUpdate() {
if (insignificantLevel == 0) {
insignificantEdit = new CompoundEdit() {
/**
*
*/
private static final long serialVersionUID = -7589808295352003936L;
@Override
public boolean isSignificant() {
return false;
}
};
insignificantLevel++;
}
}
public void testTrivialChunk() throws Exception {
content = "";
StyledDocument d = support.openDocument();
// same operations as testSingleChunk,
// but don't test modified/canUndo/canRedo state
CompoundEdit ce = beginChunk(d);
d.insertString(d.getLength(), "a", null);
d.insertString(d.getLength(), "b", null);
endChunk(d, ce);
assertEquals("data", "ab", d.getText(0, d.getLength()));
ur().undo();
assertEquals("after undo data", "", d.getText(0, d.getLength()));
ur().redo();
assertEquals("after redo data", "ab", d.getText(0, d.getLength()));
}
private CompoundEdit startCompoundEdit(UndoableEdit anEdit) {
// Track Caret and Document information of this compound edit
lastOffset = textComponent.getCaretPosition();
lastLength = textComponent.getDocument().getLength();
// 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);
undoAction.updateUndoState();
redoAction.updateRedoState();
return compoundEdit;
}
private UndoableEditDelegate(UndoableEdit ed, BaseDocument doc, InstantRefactoringPerformer performer) {
DataObject dob = (DataObject) doc.getProperty(BaseDocument.StreamDescriptionProperty);
this.ces = dob.getLookup().lookup(CloneableEditorSupport.class);
this.inner = new CompoundEdit();
this.inner.addEdit(ed);
this.delegate = ed;
this.performer = performer;
}
public void testSingleChunk() throws Exception {
content = "";
StyledDocument d = support.openDocument();
assertFalse("initially: not modified", support.isModified());
assertFalse("initially: no undo", ur().canUndo());
assertFalse("initially: no redo", ur().canRedo());
CompoundEdit ce = beginChunk(d);
assertFalse("start chunk: not modified", support.isModified());
assertFalse("start chunk: no undo", ur().canUndo());
assertFalse("start chunk: no redo", ur().canRedo());
d.insertString(d.getLength(), "a", null);
assertTrue("insert: modified", support.isModified());
assertTrue("insert: can undo", ur().canUndo());
assertFalse("insert: no redo", ur().canRedo());
d.insertString(d.getLength(), "b", null);
endChunk(d, ce);
assertEquals("chunk: data", "ab", d.getText(0, d.getLength()));
assertTrue("endChunk: modified", support.isModified());
assertTrue("endChunk: can undo", ur().canUndo());
assertFalse("endChunk: no redo", ur().canRedo());
ur().undo();
assertEquals("after undo: data", "", d.getText(0, d.getLength()));
assertFalse("undo: not modified", support.isModified());
assertFalse("undo: no undo", ur().canUndo());
assertTrue("undo: can redo", ur().canRedo());
ur().redo();
assertEquals("after redo: data", "ab", d.getText(0, d.getLength()));
assertTrue("redo: modified", support.isModified());
assertTrue("redo: can undo", ur().canUndo());
assertFalse("redo: no redo", ur().canRedo());
}
public void testNestedChunks() throws Exception {
content = "";
StyledDocument d = support.openDocument();
CompoundEdit ce1 = beginChunk(d);
d.insertString(d.getLength(), "a", null);
d.insertString(d.getLength(), "b", null);
CompoundEdit ce2 = beginChunk(d); // creates a separate undoable chunk
d.insertString(d.getLength(), "c", null);
d.insertString(d.getLength(), "d", null);
endChunk(d, ce1);
d.insertString(d.getLength(), "e", null);
d.insertString(d.getLength(), "f", null);
endChunk(d, ce2);
assertEquals("data", "abcdef", d.getText(0, d.getLength()));
// following fails if nesting not supported
ur().undo();
assertEquals("undo1", "abcd", d.getText(0, d.getLength()));
ur().undo();
assertEquals("undo2", "ab", d.getText(0, d.getLength()));
ur().undo();
assertEquals("undo3", "", d.getText(0, d.getLength()));
}
private UndoableEditDelegate(UndoableEdit ed, DataObject dob, RefactoringSession session) {
undoManager = UndoManager.getDefault();
ces = dob.getLookup().lookup(CloneableEditorSupport.class);
//this.delegate = ed;
this.inner = new CompoundEdit();
inner.addEdit(ed);
delegate = ed;
this.session = session;
}
@Override public void replace(int offset, int length, String text, AttributeSet attrs) throws BadLocationException {
if (length == 0) {
// System.out.println("insert");
super.replace(offset, length, text, attrs);
} else {
// System.out.println("replace");
compoundEdit = new CompoundEdit();
super.replace(offset, length, text, attrs);
compoundEdit.end();
super.fireUndoableEditUpdate(new UndoableEditEvent(this, compoundEdit));
compoundEdit = null;
}
}
@Override public void replace(DocumentFilter.FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException {
if (length == 0) {
fb.insertString(offset, text, attrs);
} else {
compoundEdit = new CompoundEdit();
fb.replace(offset, length, text, attrs);
compoundEdit.end();
addEdit(compoundEdit);
compoundEdit = null;
}
}
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;
}
public void testDeleteEachTenthCharFromDocument() throws Exception {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < 20; i++) {
for (int j = 0; j < 10; j++) {
sb.append((char)('0' + j));
}
}
content = sb.toString();
StyledDocument doc = support.openDocument();
assertEquals("200 chars there", 200, doc.getLength());
CompoundEdit bigEdit = new CompoundEdit();
support.getUndoRedo().undoableEditHappened(new UndoableEditEvent(doc, bigEdit));
assertTrue("Big edit will consume other edits", bigEdit.isInProgress());
for (int i = 199; i >= 0; i -= 10) {
doc.remove(i, 1);
}
assertTrue("Big edit was still in consume mode", bigEdit.isInProgress());
bigEdit.end();
assertFalse("Big edit is over", bigEdit.isInProgress());
assertTrue("Document is modified", modified);
assertTrue("We can undo", support.getUndoRedo().canUndo());
if (doc.getText(0, doc.getLength()).indexOf('9') != -1) {
fail("There should be no 9 in the doc:\n" + doc.getText(0, doc.getLength()));
}
support.getUndoRedo().undo();
assertEquals("Again 200", 200, doc.getLength());
assertFalse("Not modified anymore", modified);
assertTrue("We can redo", support.getUndoRedo().canRedo());
support.getUndoRedo().redo();
assertTrue("Document is modified", modified);
assertTrue("We can undo", support.getUndoRedo().canUndo());
if (doc.getText(0, doc.getLength()).indexOf('9') != -1) {
fail("There should be no 9 in the doc:\n" + doc.getText(0, doc.getLength()));
}
}
public void testDeleteEachTenthCharOnModifiedDocument() throws Exception {
StyledDocument doc = support.openDocument();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < 20; i++) {
for (int j = 0; j < 10; j++) {
sb.append((char)('0' + j));
}
}
assertEquals("empty", 0, doc.getLength());
doc.insertString(0, sb.toString(), null);
assertEquals("200 chars there", 200, doc.getLength());
CompoundEdit bigEdit = new CompoundEdit();
support.getUndoRedo().undoableEditHappened(new UndoableEditEvent(doc, bigEdit));
assertTrue("Big edit will consume other edits", bigEdit.isInProgress());
for (int i = 199; i >= 0; i -= 10) {
doc.remove(i, 1);
}
assertTrue("Big edit was still in consume mode", bigEdit.isInProgress());
bigEdit.end();
assertFalse("Big edit is over", bigEdit.isInProgress());
assertTrue("Document is modified", modified);
assertTrue("We can undo", support.getUndoRedo().canUndo());
if (doc.getText(0, doc.getLength()).indexOf('9') != -1) {
fail("There should be no 9 in the doc:\n" + doc.getText(0, doc.getLength()));
}
support.getUndoRedo().undo();
assertEquals("Again 200", 200, doc.getLength());
assertTrue("Still modified", modified);
assertTrue("We can redo", support.getUndoRedo().canRedo());
support.getUndoRedo().redo();
assertTrue("Document is modified", modified);
assertTrue("We can undo", support.getUndoRedo().canUndo());
if (doc.getText(0, doc.getLength()).indexOf('9') != -1) {
fail("There should be no 9 in the doc:\n" + doc.getText(0, doc.getLength()));
}
}
public void testUndoRedoUndoEdits() throws Exception {
final StyledDocument d = support.openDocument();
UndoRedo.Manager ur = support.getUndoRedo();
UndoRedoManager urMgr = null;
if (ur instanceof UndoRedoManager) {
urMgr = (UndoRedoManager) ur;
}
d.insertString(d.getLength(), "a", null);
final CompoundEdit bigEdit = new CompoundEdit();
d.insertString(d.getLength(), "b", null);
bigEdit.end();
support.saveDocument();
// setting the property to populate urMgr.onSaveTasksEdit field
d.putProperty("beforeSaveRunnable", new Runnable() {
public void run() {
Runnable beforeSaveStart = (Runnable) d.getProperty("beforeSaveStart");
if (beforeSaveStart != null) {
beforeSaveStart.run();
support.getUndoRedo().undoableEditHappened(new UndoableEditEvent(d, bigEdit));
}
}
});
urMgr.undo();
support.saveDocument();
d.putProperty("beforeSaveRunnable", null);
assertEquals("after undo data", "a", d.getText(0, d.getLength()));
urMgr.redo();
support.saveDocument();
assertEquals("after redo data", "ab", d.getText(0, d.getLength()));
urMgr.undo();
assertEquals("after redo data", "a", d.getText(0, d.getLength()));
}
CompoundEdit beginChunk(Document d) {
sendUndoableEdit(d, CloneableEditorSupport.BEGIN_COMMIT_GROUP);
return null;
}
void endChunk(Document d, CompoundEdit ce) {
sendUndoableEdit(d, CloneableEditorSupport.END_COMMIT_GROUP);
}
/** this also tests mixing regular and chunks */
public void testExtraEndChunk() throws Exception {
content = "";
StyledDocument d = support.openDocument();
CompoundEdit ce = beginChunk(d);
d.insertString(d.getLength(), "a", null);
d.insertString(d.getLength(), "b", null);
endChunk(d, ce);
assertEquals("chunk: data", "ab", d.getText(0, d.getLength()));
Level level = disableWarning();
try {
endChunk(d, ce);
endChunk(d, ce);
assertEquals("extraEnd: data", "ab", d.getText(0, d.getLength()));
assertTrue("extraEnd: modified", support.isModified());
assertTrue("extraEnd: can undo", ur().canUndo());
assertFalse("extraEnd: no redo", ur().canRedo());
d.insertString(d.getLength(), "c", null);
d.insertString(d.getLength(), "d", null);
endChunk(d, ce);
assertEquals("extraEnd2: data", "abcd", d.getText(0, d.getLength()));
ur().undo();
endChunk(d, ce);
if (!documentSupportsUndoMergingOfWords()) {
assertEquals("undo1: data", "abc", d.getText(0, d.getLength()));
ur().undo();
}
assertEquals("undo2: data", "ab", d.getText(0, d.getLength()));
ur().undo();
endChunk(d, ce);
assertEquals("undo3: data", "", d.getText(0, d.getLength()));
ur().redo();
assertEquals("redo1: data", "ab", d.getText(0, d.getLength()));
ur().redo();
endChunk(d, ce);
if (!documentSupportsUndoMergingOfWords()) {
assertEquals("redo2: data", "abc", d.getText(0, d.getLength()));
ur().redo();
}
assertEquals("redo3: data", "abcd", d.getText(0, d.getLength()));
} finally {
enableWarning(level);
}
}
public void testUndoRedoWhileActiveChunk() throws Exception {
content = "";
StyledDocument d = support.openDocument();
CompoundEdit ce = beginChunk(d);
d.insertString(d.getLength(), "a", null);
d.insertString(d.getLength(), "b", null);
assertEquals("before undo: data", "ab", d.getText(0, d.getLength()));
ur().undo();
// These asserts assume that an undo in the middle of a chunk
// is an undo on the whole chunk so far.
assertEquals("after undo: data", "", d.getText(0, d.getLength()));
assertFalse("after undo: not modified", support.isModified());
assertFalse("after undo: no undo", ur().canUndo());
assertTrue("after undo: can redo", ur().canRedo());
// note still in the chunk.
ur().redo();
assertEquals("after redo: data", "ab", d.getText(0, d.getLength()));
assertTrue("after redo: modified", support.isModified());
assertTrue("after redo: can undo", ur().canUndo());
assertFalse("after redo: no redo", ur().canRedo());
ur().undo();
assertEquals("after undo: data", "", d.getText(0, d.getLength()));
// note still in the chunk.
d.insertString(d.getLength(), "c", null);
d.insertString(d.getLength(), "d", null);
endChunk(d, ce);
assertEquals("after endChunk: data", "cd", d.getText(0, d.getLength()));
assertTrue("after endChunk: modified", support.isModified());
assertTrue("after endChunk: can undo", ur().canUndo());
assertFalse("after endChunk: no redo", ur().canRedo());
ur().undo();
assertEquals("undo after endChunk: data", "", d.getText(0, d.getLength()));
assertFalse("undo after endChunk: not modified", support.isModified());
assertFalse("undo after endChunk: no undo", ur().canUndo());
assertTrue("undo after endChunk: can redo", ur().canRedo());
}
public void testSaveDocumentWhileActiveChunkCommon(boolean doFailCase) throws Exception {
content = "";
StyledDocument d = support.openDocument();
CompoundEdit ce = beginChunk(d);
d.insertString(d.getLength(), "a", null);
d.insertString(d.getLength(), "b", null);
support.saveDocument (); // creates a separate undoable chunk
assertFalse("save: not modified", support.isModified());
assertTrue("save: can undo", ur().canUndo());
assertFalse("save: no redo", ur().canRedo());
d.insertString(d.getLength(), "c", null);
d.insertString(d.getLength(), "d", null);
endChunk(d, ce);
assertEquals("insert, after save: data", "abcd", d.getText(0, d.getLength()));
assertTrue("insert, after save: modified", support.isModified());
assertTrue("insert, after save: can undo", ur().canUndo());
assertFalse("insert, after save: no redo", ur().canRedo());
ur().undo();
assertEquals("undo, at save: data", "ab", d.getText(0, d.getLength()));
assertFalse("undo, at save: not modified", support.isModified());
assertTrue("undo, at save: can undo", ur().canUndo());
assertTrue("undo, at save: can redo", ur().canRedo());
ur().undo();
assertEquals("undo, before save: data", "", d.getText(0, d.getLength()));
if(doFailCase) {
// ****************************************************************
// CES BUG???
assertTrue("undo, before save: modified", support.isModified());
// ****************************************************************
}
assertFalse("undo, before save: can undo", ur().canUndo());
assertTrue("undo, before save: can redo", ur().canRedo());
ur().redo();
assertEquals("redo, at save: data", "ab", d.getText(0, d.getLength()));
assertFalse("redo, at save: not modified", support.isModified());
assertTrue("redo, at save: can undo", ur().canUndo());
assertTrue("redo, at save: can redo", ur().canRedo());
}
protected CompoundEdit createModelUndoableEdit() {
return new ModelUndoableEdit();
}
@Override
protected CompoundEdit createCompoundEdit() {
return createModelUndoableEdit();
}
private CommandProcessor(){
this.editor = new GUIEditor();
list = new LinkedList<Command>();
this.compoundEdit = new CompoundEdit();
}