Mega Code Archive

 
Categories / Java / Design Pattern
 

State pattern in Java 2

/* The Design Patterns Java Companion Copyright (C) 1998, by James W. Cooper IBM Thomas J. Watson Research Center */ import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Insets; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionAdapter; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.util.Vector; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JToggleButton; import javax.swing.JToolBar; public class StateDraw extends JFrame implements ActionListener {   JToolBar tbar;   Mediator med;   public StateDraw() {     super("State Drawing");     addWindowListener(new WindowAdapter() {       public void windowClosing(WindowEvent e) {         System.exit(0);       }     });     JPanel jp = new JPanel();     getContentPane().add(jp);     med = new Mediator();     jp.setLayout(new BorderLayout());     tbar = new JToolBar();     tbar.setFloatable(false);     jp.add("North", tbar);     PickButton pick = new PickButton(this, med);     tbar.add(pick);     tbar.addSeparator();     RectButton rect = new RectButton(this, med);     tbar.add(rect);     FillButton fill = new FillButton(this, med);     tbar.add(fill);     CircleButton circ = new CircleButton(this, med);     tbar.add(circ);     tbar.addSeparator();     ClearButton clr = new ClearButton(this, med);     tbar.add(clr);     JCanvas canvas = new JCanvas(med);     jp.add("Center", canvas);     MouseApp map = new MouseApp(med);     canvas.addMouseListener(map);     MouseMoveApp mvap = new MouseMoveApp(med);     canvas.addMouseMotionListener(mvap);     setSize(new Dimension(400, 300));     setVisible(true);   }   public void actionPerformed(ActionEvent e) {     Command comd = (Command) e.getSource();     comd.Execute();   }   static public void main(String[] argv) {     new StateDraw();   } } class MouseApp extends MouseAdapter {   Mediator med;   public MouseApp(Mediator md) {     super();     med = md;   }   public void mousePressed(MouseEvent e) {     med.mouseDown(e.getX(), e.getY());   }   public void mouseReleased(MouseEvent e) {     med.mouseUp(e.getX(), e.getY());   } } class MouseMoveApp extends MouseMotionAdapter {   Mediator med;   public MouseMoveApp(Mediator md) {     super();     med = md;   }   public void mouseDragged(MouseEvent e) {     med.mouseDrag(e.getX(), e.getY());   } } class ArrowState extends State {   private Mediator med;   public ArrowState(Mediator md) {     med = md;   }   public void mouseDown(int x, int y) {     Vector drawings = med.getDrawings();     for (int i = 0; i < drawings.size(); i++) {       Drawing d = (Drawing) drawings.elementAt(i);       if (d.contains(x, y))         med.setSelected(d);     }   } } class CircleState extends State {   private Mediator med; //save Mediator   public CircleState(Mediator md) {     med = md;   }   //Draw circle where mouse clicks   public void mouseDown(int x, int y) {     med.addDrawing(new visCircle(x, y));   } } class ClearButton extends JButton implements Command {   Mediator med;   public ClearButton(ActionListener act, Mediator md) {     super("C");     setToolTipText("Clear");     addActionListener(act);     med = md;   }   public void Execute() {     med.clear();   } } class CircleButton extends JToggleButton implements Command {   Mediator med;   public CircleButton(ActionListener act, Mediator md) {     super(" ");     setSize(new Dimension(35, 35));     setBorderPainted(true);     setMargin(new Insets(5, 12, 5, 12));     setToolTipText("Draw circle");     addActionListener(act);     med = md;     med.registerCircleButton(this);   }   public Dimension getPreferredSize() {     return new Dimension(35, 35);   }   public void paint(Graphics g) {     super.paint(g);     int h = getHeight();     int w = getWidth();     g.setColor(Color.black);     g.drawArc(2, 2, h - 4, h - 4, 0, 360);   }   public void Execute() {     med.startCircle();   } } class State {   public void mouseDown(int x, int y) {   }   public void mouseUp(int x, int y) {   }   public void mouseDrag(int x, int y) {   }   public void select(Drawing d, Color c) {   } } interface Command {   public void Execute(); } class FillState extends State {   private Mediator med; //save Mediator   private Color color; //save current color   public FillState(Mediator md) {     med = md;   }   //Fill drawing if selected   public void select(Drawing d, Color c) {     color = c;     if (d != null) {       d.setFill(c); //fill that drawing     }   }   //Fill drawing if you click inside one   public void mouseDown(int x, int y) {     Vector drawings = med.getDrawings();     for (int i = 0; i < drawings.size(); i++) {       Drawing d = (Drawing) drawings.elementAt(i);       if (d.contains(x, y))         d.setFill(color); //fill drawing     }   } } class JCanvas extends JPanel {   Mediator med;   public JCanvas(Mediator md) {     med = md;     med.registerCanvas(this);     setBackground(Color.white);   }   public void paint(Graphics g) {     super.paint(g);     med.reDraw(g);   } } class Mediator {   boolean startRect;   boolean dSelected;   Vector drawings;   Vector undoList;   RectButton rectButton;   FillButton fillButton;   CircleButton circButton;   PickButton arrowButton;   JPanel canvas;   Drawing selectedDrawing;   StateManager stMgr;   public Mediator() {     startRect = false;     dSelected = false;     drawings = new Vector();     undoList = new Vector();     stMgr = new StateManager(this);   }   public void startRectangle() {     stMgr.setRect();     arrowButton.setSelected(false);     circButton.setSelected(false);     fillButton.setSelected(false);   }   public void startCircle() {     stMgr.setCircle();     rectButton.setSelected(false);     arrowButton.setSelected(false);     fillButton.setSelected(false);   }   public void startFill() {     stMgr.setFill();     rectButton.setSelected(false);     circButton.setSelected(false);     arrowButton.setSelected(false);     stMgr.select(selectedDrawing, Color.red);     repaint();   }   public void startArrow() {     stMgr.setArrow();     rectButton.setSelected(false);     circButton.setSelected(false);     fillButton.setSelected(false);   }   public Drawing getSelected() {     return selectedDrawing;   }   public void fillSelected() {     if (dSelected) {       selectedDrawing.setFill(Color.red);     }   }   public Vector getDrawings() {     return drawings;   }   public void addDrawing(Drawing d) {     drawings.addElement(d);   }   public void registerRectButton(RectButton rb) {     rectButton = rb;   }   public void registerCircleButton(CircleButton cb) {     circButton = cb;   }   public void registerArrowButton(PickButton ab) {     arrowButton = ab;   }   public void registerFillButton(FillButton fb) {     fillButton = fb;   }   public void registerCanvas(JPanel p) {     canvas = p;   }   public void mouseDown(int x, int y) {     stMgr.mouseDown(x, y);     repaint();   }   public void mouseUp(int x, int y) {     stMgr.mouseUp(x, y);   }   public void unpick() {     dSelected = false;     if (selectedDrawing != null) {       selectedDrawing.setSelected(false);       selectedDrawing = null;       repaint();     }   }   public void rememberPosition() {     if (dSelected) {       //Memento m = new Memento(d);       //undoList.addElement(m);     }   }   public void setSelected(Drawing d) {     if (d != null) {       dSelected = true;       selectedDrawing = d;       d.setSelected(true);       repaint();     }   }   public void pickRect(int x, int y) {   }   public void clear() {     drawings = new Vector();     undoList = new Vector();     dSelected = false;     selectedDrawing = null;     repaint();   }   private void repaint() {     canvas.repaint();   }   public void mouseDrag(int x, int y) {     stMgr.mouseDrag(x, y);   }   public void reDraw(Graphics g) {     g.setColor(Color.black);     for (int i = 0; i < drawings.size(); i++) {       Drawing v = (Drawing) drawings.elementAt(i);       v.draw(g);     }   }   public void undo() {     if (undoList.size() > 0) {       //get last element in undo list       Object obj = undoList.lastElement();       undoList.removeElement(obj); //and remove it       //if this is an Integer, the last action was a new rectangle       if (obj instanceof Integer) {         //remove last created rectangle         Object drawObj = drawings.lastElement();         drawings.removeElement(drawObj);       }       //if this is a Memento, the last action was a move       if (obj instanceof Memento) {         //get the Memento         Memento m = (Memento) obj;         m.restore(); //and restore the old position       }       repaint();     }   } } class RectButton extends JToggleButton implements Command {   Mediator med;   public RectButton(ActionListener act, Mediator md) {     super(" ");     setSize(new Dimension(35, 35));     setBorderPainted(true);     setMargin(new Insets(5, 12, 5, 12));     setToolTipText("Draw rectangle");     addActionListener(act);     med = md;     med.registerRectButton(this);   }   public Dimension getPreferredSize() {     return new Dimension(35, 35);   }   public void paint(Graphics g) {     super.paint(g);     int h = getHeight();     int w = getWidth();     g.setColor(Color.black);     g.drawRect(4, 4, w - 8, h - 8);   }   public void Execute() {     med.startRectangle();   } } class UndoButton extends JButton implements Command {   Mediator med;   public UndoButton(ActionListener act, Mediator md) {     super("U");     //setSize(new Dimension(25,25));     setMargin(new Insets(5, 12, 5, 12));     setToolTipText("Undo");     addActionListener(act);     med = md;   }   public void Execute() {     med.undo();   } } class FillButton extends JToggleButton implements Command {   Mediator med;   public FillButton(ActionListener act, Mediator md) {     super(" ");     setSize(new Dimension(35, 35));     setBorderPainted(true);     setMargin(new Insets(5, 12, 5, 12));     setToolTipText("Fill rectangle");     addActionListener(act);     med = md;     med.registerFillButton(this);   }   public Dimension getPreferredSize() {     return new Dimension(35, 35);   }   public void paint(Graphics g) {     super.paint(g);     int h = getHeight();     int w = getWidth();     g.setColor(Color.black);     g.drawRect(4, 4, w - 8, h - 8);     g.setColor(Color.red);     g.fillRect(4, 10, w - 8, h - 14);   }   public void Execute() {     if (isSelected()) {       med.startFill();     }   } } class Memento {   public Memento(Drawing d) {   }   public void restore() {   } } class RectState extends State {   private Mediator med; //save the Mediator here   public RectState(Mediator md) {     med = md;   }   //create a new Rectangle where mode clicks   public void mouseDown(int x, int y) {     med.addDrawing(new visRectangle(x, y));   } } class StateManager {   private State currentState;   RectState rState;   ArrowState aState;   CircleState cState;   FillState fState;   public StateManager(Mediator med) {     rState = new RectState(med);     cState = new CircleState(med);     aState = new ArrowState(med);     fState = new FillState(med);     currentState = aState;   }   public void setRect() {     currentState = rState;   }   public void setCircle() {     currentState = cState;   }   public void setFill() {     currentState = fState;   }   public void setArrow() {     currentState = aState;   }   public void mouseDown(int x, int y) {     currentState.mouseDown(x, y);   }   public void mouseUp(int x, int y) {     currentState.mouseUp(x, y);   }   public void mouseDrag(int x, int y) {     currentState.mouseDrag(x, y);   }   public void select(Drawing d, Color c) {     currentState.select(d, c);   } } class Drawing {   protected int x, y, w, h;   protected Rectangle rect;   protected boolean selected;   protected boolean filled;   protected Color fillColor;   //-------------------------------------------   public void setSelected(boolean b) {     selected = b;   }   public void draw(Graphics g) {   }   public void move(int xpt, int ypt) {     x = xpt;     y = ypt;   }   public boolean contains(int x, int y) {     return rect.contains(x, y);   }   protected void saveAsRect() {     rect = new Rectangle(x - w / 2, y - h / 2, w, h);   }   protected void setFill(Color c) {     filled = true;     fillColor = c;   } } class visCircle extends Drawing {   public visCircle(int xpt, int ypt) {     x = xpt;     y = ypt;     w = 40;     h = 30;     saveAsRect();   }   //-------------------------------------------   public void draw(Graphics g) {     g.drawArc(x, y, w, h, 0, 360);     if (filled) {       g.setColor(fillColor);       g.fillArc(x, y, w, h, 0, 360);     }     if (selected) {       g.setColor(Color.black);       g.fillRect(x + w / 2, y - 2, 4, 4);       g.fillRect(x - 2, y + h / 2, 4, 4);       g.fillRect(x + w / 2, y + h - 2, 4, 4);       g.fillRect(x + w - 2, y + h / 2, 4, 4);     }   } } //=============================================== class circleMemento extends Memento {   visCircle circ;   //saved fields- remember internal fields   //of the specified visual rectangle   int x, y, w, h;   public circleMemento(visCircle r) {     super(r);     circ = r;     x = circ.x;     y = circ.y;     w = circ.w;     h = circ.h;   }   //-------------------------------------------   public void restore() {     //restore the internal state of     //the specified rectangle     circ.x = x;     circ.y = y;     circ.h = h;     circ.w = w;   } } class visRectangle extends Drawing {   public visRectangle(int xpt, int ypt) {     x = xpt;     y = ypt;     w = 40;     h = 30;     saveAsRect();   }   //-------------------------------------------   public void draw(Graphics g) {     g.drawRect(x, y, w, h);     if (filled) {       g.setColor(fillColor);       g.fillRect(x, y, w, h);     }     if (selected) {       g.setColor(Color.black);       g.fillRect(x + w / 2, y - 2, 4, 4);       g.fillRect(x - 2, y + h / 2, 4, 4);       g.fillRect(x + w / 2, y + h - 2, 4, 4);       g.fillRect(x + w - 2, y + h / 2, 4, 4);     }   } } class rectMemento extends Memento {   visRectangle rect;   //saved fields- remember internal fields   //of the specified visual rectangle   int x, y, w, h;   public rectMemento(visRectangle r) {     super(r);     rect = r;     x = rect.x;     y = rect.y;     w = rect.w;     h = rect.h;   }   //-------------------------------------------   public void restore() {     //restore the internal state of     //the specified rectangle     rect.x = x;     rect.y = y;     rect.h = h;     rect.w = w;   } } class PickButton extends JToggleButton implements Command {   Mediator med;   public PickButton(ActionListener act, Mediator md) {     super(new ImageIcon("arrow.gif"));     setSize(new Dimension(35, 35));     setBorderPainted(true);     setMargin(new Insets(0, 0, 0, 0));     setToolTipText("Select drawing element");     addActionListener(act);     med = md;     med.registerArrowButton(this);   }   //-------------------------------------------   public void Execute() {     med.startArrow();   } }