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