State pattern in Java 2 : State Pattern « Design Pattern « Java






State pattern in Java 2

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; publicclass StateDraw extends JFrame implements ActionListener { JToolBar tbar; Mediator med; public StateDraw() { super("State Drawing"); addWindowListener(new WindowAdapter() { publicvoid 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); } publicvoid actionPerformed(ActionEvent e) { Command comd = (Command) e.getSource(); comd.Execute(); } staticpublicvoid main(String[] argv) { new StateDraw(); } } class MouseApp extends MouseAdapter { Mediator med; public MouseApp(Mediator md) { super(); med = md; } publicvoid mousePressed(MouseEvent e) { med.mouseDown(e.getX(), e.getY()); } publicvoid mouseReleased(MouseEvent e) { med.mouseUp(e.getX(), e.getY()); } } class MouseMoveApp extends MouseMotionAdapter { Mediator med; public MouseMoveApp(Mediator md) { super(); med = md; } publicvoid mouseDragged(MouseEvent e) { med.mouseDrag(e.getX(), e.getY()); } } class ArrowState extends State { private Mediator med; public ArrowState(Mediator md) { med = md; } publicvoid 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 publicvoid 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; } publicvoid 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() { returnnew Dimension(35, 35); } publicvoid 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); } publicvoid Execute() { med.startCircle(); } } class State { publicvoid mouseDown(int x, int y) { } publicvoid mouseUp(int x, int y) { } publicvoid mouseDrag(int x, int y) { } publicvoid select(Drawing d, Color c) { } } interface Command { publicvoid 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 publicvoid select(Drawing d, Color c) { color = c; if (d != null) { d.setFill(c); //fill that drawing  } } //Fill drawing if you click inside one publicvoid 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); } publicvoid 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); } publicvoid startRectangle() { stMgr.setRect(); arrowButton.setSelected(false); circButton.setSelected(false); fillButton.setSelected(false); } publicvoid startCircle() { stMgr.setCircle(); rectButton.setSelected(false); arrowButton.setSelected(false); fillButton.setSelected(false); } publicvoid startFill() { stMgr.setFill(); rectButton.setSelected(false); circButton.setSelected(false); arrowButton.setSelected(false); stMgr.select(selectedDrawing, Color.red); repaint(); } publicvoid startArrow() { stMgr.setArrow(); rectButton.setSelected(false); circButton.setSelected(false); fillButton.setSelected(false); } public Drawing getSelected() { return selectedDrawing; } publicvoid fillSelected() { if (dSelected) { selectedDrawing.setFill(Color.red); } } public Vector getDrawings() { return drawings; } publicvoid addDrawing(Drawing d) { drawings.addElement(d); } publicvoid registerRectButton(RectButton rb) { rectButton = rb; } publicvoid registerCircleButton(CircleButton cb) { circButton = cb; } publicvoid registerArrowButton(PickButton ab) { arrowButton = ab; } publicvoid registerFillButton(FillButton fb) { fillButton = fb; } publicvoid registerCanvas(JPanel p) { canvas = p; } publicvoid mouseDown(int x, int y) { stMgr.mouseDown(x, y); repaint(); } publicvoid mouseUp(int x, int y) { stMgr.mouseUp(x, y); } publicvoid unpick() { dSelected = false; if (selectedDrawing != null) { selectedDrawing.setSelected(false); selectedDrawing = null; repaint(); } } publicvoid rememberPosition() { if (dSelected) { //Memento m = new Memento(d); //undoList.addElement(m);  } } publicvoid setSelected(Drawing d) { if (d != null) { dSelected = true; selectedDrawing = d; d.setSelected(true); repaint(); } } publicvoid pickRect(int x, int y) { } publicvoid clear() { drawings = new Vector(); undoList = new Vector(); dSelected = false; selectedDrawing = null; repaint(); } privatevoid repaint() { canvas.repaint(); } publicvoid mouseDrag(int x, int y) { stMgr.mouseDrag(x, y); } publicvoid reDraw(Graphics g) { g.setColor(Color.black); for (int i = 0; i < drawings.size(); i++) { Drawing v = (Drawing) drawings.elementAt(i); v.draw(g); } } publicvoid 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 instanceofInteger) { //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() { returnnew Dimension(35, 35); } publicvoid paint(Graphics g) { super.paint(g); int h = getHeight(); int w = getWidth(); g.setColor(Color.black); g.drawRect(4, 4, w - 8, h - 8); } publicvoid 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; } publicvoid 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() { returnnew Dimension(35, 35); } publicvoid 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); } publicvoid Execute() { if (isSelected()) { med.startFill(); } } } class Memento { public Memento(Drawing d) { } publicvoid 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 publicvoid 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; } publicvoid setRect() { currentState = rState; } publicvoid setCircle() { currentState = cState; } publicvoid setFill() { currentState = fState; } publicvoid setArrow() { currentState = aState; } publicvoid mouseDown(int x, int y) { currentState.mouseDown(x, y); } publicvoid mouseUp(int x, int y) { currentState.mouseUp(x, y); } publicvoid mouseDrag(int x, int y) { currentState.mouseDrag(x, y); } publicvoid select(Drawing d, Color c) { currentState.select(d, c); } } class Drawing { protectedint x, y, w, h; protected Rectangle rect; protectedboolean selected; protectedboolean filled; protected Color fillColor; //------------------------------------------- publicvoid setSelected(boolean b) { selected = b; } publicvoid draw(Graphics g) { } publicvoid move(int xpt, int ypt) { x = xpt; y = ypt; } publicboolean contains(int x, int y) { return rect.contains(x, y); } protectedvoid saveAsRect() { rect = new Rectangle(x - w / 2, y - h / 2, w, h); } protectedvoid 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(); } //------------------------------------------- publicvoid 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; } //------------------------------------------- publicvoid 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(); } //------------------------------------------- publicvoid 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; } //------------------------------------------- publicvoid 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); } //------------------------------------------- publicvoid Execute() { med.startArrow(); } } 








Related examples in the same category

1.State Pattern in Java
2.Dynamically changing the behavior of an object via composition (the State design pattern)Dynamically changing the behavior of an object via composition (the State design pattern)
close