October 2, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

Working With Design Patterns: Memento

  • January 10, 2008
  • 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

Comment and Contribute


(Maximum characters: 1200). You have characters left.



Sitemap | Contact Us

Rocket Fuel