The undo/redo for JChemPaintworks as follows:
- there is an interface org/openscience/jchempaint/controller/undoredo/IUndoRedoable.java which needs to be implemented by each undo/redoable edit (there must be such an edit for every undo/redoable action). It is implemented by classes in org/openscience/jchempaint/controller/undoredo. An example for this is org/openscience/jchempaint/controller/undoredo/AddAtomsAndBondsEdit.java. These classes do the actual undo/redo on the chemmodel, but know nothing about GUI frameworks. The application must provide a GUI specific extension for each of them.
- There is an interface org/openscience/jchempaint/controller/undoredo/IUndoRedoFactory.java, which has methods to return in instance of all the Edits (i. e. classes implementing IUndoRedoable). The application must provide an implementation returning the GUI-specific extensions mentioned above.
- An instance of main/org/openscience/jchempaint/controller/undoredo/UndoRedoHandler.java needs to be set in the Hub (if you pass null no undo/redo will be done). All action in the Hub, which actually change the model, post edits (i. e. instances of implementations of IUndoRedoable they get via an instance of IUndoRedoFactory, which is passed to the hub as well) to the UndoRedoHandler. Note that there are also some elementary actions in the hub which do not post undo/redo event (called XWithoutUndo). You can use these to compose higher level actions, which then must handle undo themselves.
- The application needs to register an org/openscience/jchempaint/controller/undoredo/IUndoListener.java on the UndoRedoHandler and then pass on the posting of edits to the actual GUI implementation of undo redo.
You can see all this in action in JCP. In JCP, there is:
- org/openscience/jchempaint/undoredo/SwingAddAtomsAndBondsEdit.java extending the AddAtomsAndBondsEdit for Swing (which means implementing an interface).
- org/openscience/jchempaint/undoredo/SwingUndoRedoFactory.java is in implementation of IUndoRedoFactory for Swing.
- The RenderPanel implements IUndoListener and passes events on to the Swing UndoManager, which is then used by actions.
- RenderPanel creates an instance of UndoRedoHandler, registers itself on it and passes it onto the hub.