Java/Design Pattern/State Pattern
Dynamically changing the behavior of an object via composition (the State design pattern)
// : c07:Transmogrify.java
// Dynamically changing the behavior of an object via composition (the State design pattern).
// From "Thinking in Java, 3rd ed." (c) Bruce Eckel 2002
// www.BruceEckel.ru. See copyright notice in CopyRight.txt.
abstract class Actor {
public abstract void act();
}
class HappyActor extends Actor {
public void act() {
System.out.println("HappyActor");
}
}
class SadActor extends Actor {
public void act() {
System.out.println("SadActor");
}
}
class Stage {
private Actor actor = new HappyActor();
public void change() {
actor = new SadActor();
}
public void performPlay() {
actor.act();
}
}
public class Transmogrify {
public static void main(String[] args) {
Stage stage = new Stage();
stage.performPlay();
stage.change();
stage.performPlay();
}
} ///:~
State Pattern in Java
//[C] 2002 Sun Microsystems, Inc.---
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
public class RunStatePattern {
public static void main(String[] arguments) {
System.out.println("Example for the State pattern");
System.out.println();
if (!(new File("appointments.ser").exists())) {
DataCreator.serialize("appointments.ser");
}
System.out.println("Creating CalendarEditor");
CalendarEditor appointmentBook = new CalendarEditor();
System.out.println("");
System.out.println("Created. Appointments:");
System.out.println(appointmentBook.getAppointments());
System.out.println("Created. Creating GUI:");
StateGui application = new StateGui(appointmentBook);
application.createGui();
System.out.println("");
}
}
interface State {
public void save();
public void edit();
}
interface Contact extends Serializable {
public static final String SPACE = " ";
public String getFirstName();
public String getLastName();
public String getTitle();
public String getOrganization();
public void setFirstName(String newFirstName);
public void setLastName(String newLastName);
public void setTitle(String newTitle);
public void setOrganization(String newOrganization);
}
class ContactImpl implements Contact {
private String firstName;
private String lastName;
private String title;
private String organization;
public ContactImpl() {
}
public ContactImpl(String newFirstName, String newLastName,
String newTitle, String newOrganization) {
firstName = newFirstName;
lastName = newLastName;
title = newTitle;
organization = newOrganization;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public String getTitle() {
return title;
}
public String getOrganization() {
return organization;
}
public void setFirstName(String newFirstName) {
firstName = newFirstName;
}
public void setLastName(String newLastName) {
lastName = newLastName;
}
public void setTitle(String newTitle) {
title = newTitle;
}
public void setOrganization(String newOrganization) {
organization = newOrganization;
}
public String toString() {
return firstName + SPACE + lastName;
}
}
interface Location extends Serializable {
public String getLocation();
public void setLocation(String newLocation);
}
class LocationImpl implements Location {
private String location;
public LocationImpl() {
}
public LocationImpl(String newLocation) {
location = newLocation;
}
public String getLocation() {
return location;
}
public void setLocation(String newLocation) {
location = newLocation;
}
public String toString() {
return location;
}
}
class FileLoader {
public static Object loadData(File inputFile) {
Object returnValue = null;
try {
if (inputFile.exists()) {
if (inputFile.isFile()) {
ObjectInputStream readIn = new ObjectInputStream(
new FileInputStream(inputFile));
returnValue = readIn.readObject();
readIn.close();
} else {
System.err.println(inputFile + " is a directory.");
}
} else {
System.err.println("File " + inputFile + " does not exist.");
}
} catch (ClassNotFoundException exc) {
exc.printStackTrace();
} catch (IOException exc) {
exc.printStackTrace();
}
return returnValue;
}
public static void storeData(File outputFile, Serializable data) {
try {
ObjectOutputStream writeOut = new ObjectOutputStream(
new FileOutputStream(outputFile));
writeOut.writeObject(data);
writeOut.close();
} catch (IOException exc) {
exc.printStackTrace();
}
}
}
class DataCreator {
private static final String DEFAULT_FILE = "data.ser";
private static Calendar dateCreator = Calendar.getInstance();
public static void main(String[] args) {
String fileName;
if (args.length == 1) {
fileName = args[0];
} else {
fileName = DEFAULT_FILE;
}
serialize(fileName);
}
public static void serialize(String fileName) {
try {
serializeToFile(createData(), fileName);
} catch (IOException exc) {
exc.printStackTrace();
}
}
private static Serializable createData() {
ArrayList appointments = new ArrayList();
ArrayList contacts = new ArrayList();
contacts.add(new ContactImpl("Test", "Subject", "Volunteer",
"United Patterns Consortium"));
Location location1 = new LocationImpl("Punxsutawney, PA");
appointments.add(new Appointment("Slowpokes anonymous", contacts,
location1, createDate(2001, 1, 1, 12, 01), createDate(2001, 1,
1, 12, 02)));
appointments.add(new Appointment("Java focus group", contacts,
location1, createDate(2001, 1, 1, 12, 30), createDate(2001, 1,
1, 14, 30)));
appointments
.add(new Appointment("Something else", contacts, location1,
createDate(2001, 1, 1, 12, 01), createDate(2001, 1, 1,
12, 02)));
appointments.add(new Appointment("Yet another thingie", contacts,
location1, createDate(2001, 1, 1, 12, 01), createDate(2001, 1,
1, 12, 02)));
return appointments;
}
private static void serializeToFile(Serializable content, String fileName)
throws IOException {
ObjectOutputStream serOut = new ObjectOutputStream(
new FileOutputStream(fileName));
serOut.writeObject(content);
serOut.close();
}
public static Date createDate(int year, int month, int day, int hour,
int minute) {
dateCreator.set(year, month, day, hour, minute);
return dateCreator.getTime();
}
}
class Appointment implements Serializable {
private String reason;
private ArrayList contacts;
private Location location;
private Date startDate;
private Date endDate;
public Appointment(String reason, ArrayList contacts, Location location,
Date startDate, Date endDate) {
this.reason = reason;
this.contacts = contacts;
this.location = location;
this.startDate = startDate;
this.endDate = endDate;
}
public String getReason() {
return reason;
}
public ArrayList getContacts() {
return contacts;
}
public Location getLocation() {
return location;
}
public Date getStartDate() {
return startDate;
}
public Date getEndDate() {
return endDate;
}
public void setReason(String reason) {
this.reason = reason;
}
public void setContacts(ArrayList contacts) {
this.contacts = contacts;
}
public void setLocation(Location location) {
this.location = location;
}
public void setStartDate(Date startDate) {
this.startDate = startDate;
}
public void setEndDate(Date endDate) {
this.endDate = endDate;
}
public String toString() {
return "Appointment:" + "\n Reason: " + reason + "\n Location: "
+ location + "\n Start: " + startDate + "\n End: "
+ endDate + "\n";
}
}
class CalendarEditor {
private State currentState;
private File appointmentFile;
private ArrayList appointments = new ArrayList();
private static final String DEFAULT_APPOINTMENT_FILE = "appointments.ser";
public CalendarEditor() {
this(DEFAULT_APPOINTMENT_FILE);
}
public CalendarEditor(String appointmentFileName) {
appointmentFile = new File(appointmentFileName);
try {
appointments = (ArrayList) FileLoader.loadData(appointmentFile);
} catch (ClassCastException exc) {
System.err
.println("Unable to load information. The file does not contain a list of appointments.");
}
currentState = new CleanState();
}
public void save() {
currentState.save();
}
public void edit() {
currentState.edit();
}
private class DirtyState implements State {
private State nextState;
public DirtyState(State nextState) {
this.nextState = nextState;
}
public void save() {
FileLoader.storeData(appointmentFile, appointments);
currentState = nextState;
}
public void edit() {
}
}
private class CleanState implements State {
private State nextState = new DirtyState(this);
public void save() {
}
public void edit() {
currentState = nextState;
}
}
public ArrayList getAppointments() {
return appointments;
}
public void addAppointment(Appointment appointment) {
if (!appointments.contains(appointment)) {
appointments.add(appointment);
}
}
public void removeAppointment(Appointment appointment) {
appointments.remove(appointment);
}
}
class StateGui implements ActionListener {
private JFrame mainFrame;
private JPanel controlPanel, editPanel;
private CalendarEditor editor;
private JButton save, exit;
public StateGui(CalendarEditor edit) {
editor = edit;
}
public void createGui() {
mainFrame = new JFrame("State Pattern Example");
Container content = mainFrame.getContentPane();
content.setLayout(new BoxLayout(content, BoxLayout.Y_AXIS));
editPanel = new JPanel();
editPanel.setLayout(new BorderLayout());
JTable appointmentTable = new JTable(new StateTableModel(
(Appointment[]) editor.getAppointments().toArray(
new Appointment[1])));
editPanel.add(new JScrollPane(appointmentTable));
content.add(editPanel);
controlPanel = new JPanel();
save = new JButton("Save Appointments");
exit = new JButton("Exit");
controlPanel.add(save);
controlPanel.add(exit);
content.add(controlPanel);
save.addActionListener(this);
exit.addActionListener(this);
mainFrame.addWindowListener(new WindowCloseManager());
mainFrame.pack();
mainFrame.setVisible(true);
}
public void actionPerformed(ActionEvent evt) {
Object originator = evt.getSource();
if (originator == save) {
saveAppointments();
} else if (originator == exit) {
exitApplication();
}
}
private class WindowCloseManager extends WindowAdapter {
public void windowClosing(WindowEvent evt) {
exitApplication();
}
}
private void saveAppointments() {
editor.save();
}
private void exitApplication() {
System.exit(0);
}
private class StateTableModel extends AbstractTableModel {
private final String[] columnNames = { "Appointment", "Contacts",
"Location", "Start Date", "End Date" };
private Appointment[] data;
public StateTableModel(Appointment[] appointments) {
data = appointments;
}
public String getColumnName(int column) {
return columnNames[column];
}
public int getRowCount() {
return data.length;
}
public int getColumnCount() {
return columnNames.length;
}
public Object getValueAt(int row, int column) {
Object value = null;
switch (column) {
case 0:
value = data[row].getReason();
break;
case 1:
value = data[row].getContacts();
break;
case 2:
value = data[row].getLocation();
break;
case 3:
value = data[row].getStartDate();
break;
case 4:
value = data[row].getEndDate();
break;
}
return value;
}
public boolean isCellEditable(int row, int column) {
return ((column == 0) || (column == 2)) ? true : false;
}
public void setValueAt(Object value, int row, int column) {
switch (column) {
case 0:
data[row].setReason((String) value);
editor.edit();
break;
case 1:
break;
case 2:
data[row].setLocation(new LocationImpl((String) value));
editor.edit();
break;
case 3:
break;
case 4:
break;
}
}
}
}
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();
}
}