February 25, 2021
Hot Topics:

Working With Design Patterns: Memento

  • By Jeff Langr
  • Send Email »
  • More Articles »

When you undo a command, it needs to reset the state of the PathCanvas to a prior point in time. A stored Memento object represents this prior point. The method setMemento updates the state of the PathCanvas object.

Listing 4: PathCanvas.

import java.awt.*;
import java.awt.geom.*;
import java.util.*;
import java.util.List;

public class PathCanvas extends Observable implements
   MementoOriginator, Displayable {
   private List<ColoredPath> paths =
      new ArrayList<ColoredPath>();

   public List<ColoredPath> paths() {
      return paths;

   public void add(ColoredPath path) {

   public void displayOn(Graphics2D graphics) {
      for (ColoredPath path: paths) {
         Area polygon = new Area(path.getGeneralPath());

   public Memento getMemento() {
      List<ColoredPath> pathCopies =
         new ArrayList<ColoredPath>();
      return new Memento(pathCopies);

   public void setMemento(Memento memento) {

   private void changed() {

I created the MementoOriginator interface not out of necessity, but to reinforce the class names used in the Design Patterns book. The interface is simply:

public interface MementoOriginator {
   Memento getMemento();
   void setMemento(Memento memento);

Listing 5: Memento.

import java.util.*;

public class Memento {
   private List<ColoredPath> paths;

   public Memento(List<ColoredPath> paths) {
      this.paths = paths;

   public List<ColoredPath> getPaths() {
      return paths;

The most involved piece of the puzzle is the set of commands themselves. I implemented TriangleCommand and SquareCommand to demonstrate drawing a couple different shapes. Because each command needs to support being executed, undone, and redone, I was able to move some commonality into a superclass AbstractCommand (see Listing 6).

Listing 6: AbstractCommand.

import java.awt.*;
import java.util.*;
import model.*;
import model.PathCanvas;

import commandframework.*;

abstract public class AbstractCommand implements Command {
   private Memento memento;

   private Random random = new Random();
   protected double width;
   protected double height;
   protected PathCanvas canvas;
   protected Color color;

   public AbstractCommand() {

   public AbstractCommand(PathCanvas canvas, double width,
      double height, Color color) {
      this.width = width;
      this.height = height;
      this.canvas = canvas;
      this.color = color;

   public void execute() {
      this.memento = canvas.getMemento();

   abstract protected void transform();

   public void undo() {
      Memento redoMemento = canvas.getMemento();
      memento = redoMemento;

   public void redo() {
      Memento undoMemento = canvas.getMemento();
      memento = undoMemento;

   protected double random(double max) {
      return random.nextDouble() * max;

Page 2 of 3

This article was originally published on January 10, 2008

Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Thanks for your registration, follow us on our social networks to keep up-to-date