Created
June 4, 2017 06:32
-
-
Save deyindra/5f4e7337fa8f70ad53664defca644770 to your computer and use it in GitHub Desktop.
UndoRedoList
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.List; | |
import java.util.Objects; | |
abstract class AbstractListCommand<T> { | |
protected final String opName; | |
protected final int index; | |
protected T newObject; | |
protected T oldObject; | |
protected AbstractListCommand(final int index, final String opName) { | |
this.index = index; | |
this.opName = opName; | |
} | |
protected void validate(List<T> list, boolean isSizeInclusive){ | |
if(index<0 || (isSizeInclusive? index>=list.size() : index>list.size())){ | |
throw new IllegalArgumentException("Invalid Index "+index); | |
} | |
} | |
protected abstract void undo(List<T> list); | |
protected abstract void redo(List<T> list); | |
@Override | |
public String toString() { | |
return String.format("Operation: %s, index: %s, " + | |
"newObject: %s, oldObject %s", | |
opName,index, | |
Objects.toString(newObject, "null"), | |
Objects.toString(oldObject, "null")); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.List; | |
public class AddCommand<T> extends AbstractListCommand<T> { | |
public AddCommand(final int index, T newObject) { | |
super(index, "ADD"); | |
this.newObject = newObject; | |
} | |
@Override | |
protected void undo(List<T> list) { | |
validate(list,true); | |
this.newObject = list.remove(index); | |
} | |
@Override | |
protected void redo(List<T> list) { | |
validate(list,false); | |
list.add(index,newObject); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.List; | |
public class DeleteCommand<T> extends AbstractListCommand<T> { | |
public DeleteCommand(final int index) { | |
super(index, "DELETE"); | |
} | |
@Override | |
protected void undo(List<T> list) { | |
validate(list,false); | |
list.add(index, newObject); | |
} | |
@Override | |
protected void redo(List<T> list) { | |
validate(list,true); | |
this.newObject = list.remove(index); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.ArrayList; | |
import java.util.List; | |
import java.util.Stack; | |
public class UndoRedoList<T> { | |
private List<T> list; | |
private Stack<AbstractListCommand<T>> undoStack; | |
private Stack<AbstractListCommand<T>> redoStack; | |
private AbstractListCommand<T> currentCommand; | |
public UndoRedoList() { | |
list = new ArrayList<>(); | |
undoStack = new Stack<>(); | |
redoStack = new Stack<>(); | |
currentCommand = null; | |
} | |
private void execute(int index, T object, Operation op){ | |
AbstractListCommand<T> prevCommand = currentCommand; | |
if(op == Operation.ADD){ | |
currentCommand = new AddCommand<>(index,object); | |
}else if (op == Operation.UPDATE){ | |
currentCommand = new UpdateCommand<>(index,object); | |
}else if(op == Operation.DELETE){ | |
currentCommand = new DeleteCommand<>(index); | |
} | |
undoStack.push(prevCommand); | |
currentCommand.redo(list); | |
} | |
public void add(T object){ | |
add(list.size(),object); | |
} | |
public void add(int index, T object){ | |
execute(index,object, Operation.ADD); | |
} | |
public void remove(T object){ | |
int index = list.indexOf(object); | |
remove(index); | |
} | |
public void remove(int index){ | |
execute(index,null,Operation.DELETE); | |
} | |
public void update(int index, T object){ | |
execute(index,object,Operation.UPDATE); | |
} | |
public void undo(){ | |
if(!canUndo()){ | |
throw new IllegalStateException("Can not undo!!"); | |
} | |
currentCommand.undo(list); | |
redoStack.push(currentCommand); | |
currentCommand = undoStack.pop(); | |
} | |
public void redo(){ | |
if(!canRedo()){ | |
throw new IllegalStateException("Can not redo!!"); | |
} | |
AbstractListCommand<T> prevCommand = currentCommand; | |
undoStack.push(prevCommand); | |
currentCommand = redoStack.pop(); | |
currentCommand.redo(list); | |
} | |
public boolean canUndo(){ | |
return !undoStack.isEmpty(); | |
} | |
public boolean canRedo(){ | |
return !redoStack.isEmpty(); | |
} | |
@Override | |
public String toString() { | |
return "UndoRedoList{" + | |
"list=" + list + | |
'}'; | |
} | |
private enum Operation{ | |
ADD, UPDATE, DELETE | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.List; | |
public class UpdateCommand<T> extends AbstractListCommand<T> { | |
public UpdateCommand(final int index, T newObject) { | |
super(index, "UPDATE"); | |
this.newObject = newObject; | |
} | |
@Override | |
protected void undo(List<T> list) { | |
validate(list,true); | |
this.newObject = list.set(index, oldObject); | |
} | |
@Override | |
protected void redo(List<T> list) { | |
validate(list,true); | |
this.oldObject = list.set(index, newObject); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment