/*	Joseph Bergin 12.97*/import java.awt.*;import java.applet.Applet;import java.awt.event.*;import java.util.*;public class PaintDrawApplet extends Applet{	private TestCanvas drawArea = new TestCanvas();	private Toolkit myToolkit = Toolkit.getDefaultToolkit();	private Frame myFrame;	private Figure selectedFigure = null;	private boolean dragging = false;				public PaintDrawApplet(Frame f){myFrame = f; }		public void init() 	{	add (drawArea);		drawArea.setBackground(Color.white);		add(moveButton);		add(printButton);		figures.addElement(a);		figures.addElement(b);		figures.addElement(c);		figures.addElement(d);		connections.addElement(ab);		connections.addElement(ca);		connections.addElement(bc);		connections.addElement(ad);		connections.addElement(bd);		}		RoundRectangleFigure a = new RoundRectangleFigure("A", 30, 50, 50, 50);	OvalFigure b = new OvalFigure("B", 200, 50, 50, 50);	RectangleFigure c = new RectangleFigure("C", 30, 150, 50, 50);	OvalFigure d = new OvalFigure("D", 100, 100, 60, 30);	Connection ab = a.connect("AB", b);	Connection ca = c.connect("CA", a);	Connection bc = b.connect("BC", c);	Connection ad = a.connect("AD", d);	Connection bd = b.connect("BD", d);	Vector figures = new Vector();	Vector connections = new Vector();		Button moveButton = new MoveButton();	Button printButton = new PrintButton();		public void print(){drawArea.print();}		public Dimension getPreferredSize()	{	return myFrame.getSize();	}		public Dimension getMinimumSize()	{	return new Dimension(500, 300);	}		class TestCanvas extends Canvas	{	Image offscreen = null;		final boolean doubleBuffering = true;		Graphics og; // The offscreen graphics context. 				public TestCanvas()		{	addMouseListener(new HitListener());			addMouseMotionListener(new DragListener());							}				public void invalidate()		{	super.invalidate();			offscreen = null;		}				public Dimension getPreferredSize()		{	Dimension d = PaintDrawApplet.this.getPreferredSize();			return new Dimension(d.width - 100, d.height);		} 		public Dimension getMinimumSize()		{	return new Dimension(400, 300);		}				public void update(Graphics g)		{	if(doubleBuffering) paint(g); else super.update(g);		}				public void flip(Figure f)		{	Graphics g = getGraphics();			g.setXORMode(getBackground());			f.drawOutline(g); // Try draw here instead of drawOutline for a different effect			g.dispose();		}		private void doDraw(Graphics g)		{	Enumeration e = connections.elements();			while(e.hasMoreElements())				((Figure) e.nextElement()).draw( g);			e = figures.elements();			while(e.hasMoreElements())				((Figure) e.nextElement()).draw( g);		} 		public void paint( Graphics g ) 		{	if(!doubleBuffering)			{ 	doDraw(g);				return;			}			Dimension d = getSize(); int h = d.height; int w = d.width;			if(offscreen == null) offscreen = createImage(w, h);			Graphics og = offscreen.getGraphics();			og.setClip(0, 0, w, h);//			doDraw(og); // equivalent to the next few statements (marginally faster)			Enumeration e = connections.elements();			while(e.hasMoreElements())				((Figure) e.nextElement()).draw( og);			e = figures.elements();			while(e.hasMoreElements())				((Figure) e.nextElement()).draw( og);									g.drawImage(offscreen, 0, 0, null);	    	og.setColor(getBackground()); // Clear the image for next paint.	   		og.fillRect(0, 0, w, h);			og.dispose();		}				public void print()		{	PrintJob printing = myToolkit.getPrintJob(myFrame, "Testing", null);			if(printing == null)				System.out.println("No print job");			else			{	Graphics drawer = printing.getGraphics();				if(drawer == null) 					System.out.println("No Graphics.");				else				{	paint(drawer);					drawer.dispose();				}				printing.end();			}		}	}		class MoveButton extends Button implements ActionListener	{	public MoveButton()		{	super("Move");			addActionListener(this);		}				public void actionPerformed(ActionEvent e)		{	b.move(b.location().x, b.location().y + 20);			drawArea.repaint();		}	}	class PrintButton extends Button implements ActionListener	{	public PrintButton()		{	super("Print");			addActionListener(this);		}				public void actionPerformed(ActionEvent e)		{	PaintDrawApplet.this.print();		}	}		class HitListener extends MouseAdapter	{	public void mouseClicked(MouseEvent e)		{	Point p = e.getPoint();			Enumeration v = figures.elements();			selectedFigure = null;			boolean doDraw = false;			while(v.hasMoreElements())			{	Figure f = (Figure)v.nextElement();				if(f.contains(p))				{ 	if(! f.isSelected())					{ 	doDraw = true;						f.setSelected(true);						selectedFigure = f;					}				}				else				{	if(f.isSelected())					{ 	doDraw = true;						f.setSelected(false);					}				}			}			if (doDraw) drawArea.repaint();		}				public void mousePressed(MouseEvent e)		{	if(selectedFigure != null && selectedFigure.contains(e.getPoint()))				dragging = true;		}				public void mouseReleased(MouseEvent e)		{	dragging = false;			drawArea.repaint();		}	}		class DragListener extends MouseMotionAdapter	{	public void mouseDragged(MouseEvent e)		{	if(dragging)			{	drawArea.flip(selectedFigure);				selectedFigure.move(e.getPoint());				drawArea.flip(selectedFigure);			}		}	}}/* Improvements.  	Center the label. 	Size the box according to the size of the label.	Get/set colors.  	Get/set label. 	More getters/setters for Figure. 	Line as a figure.  	More shapes, including complex shapes needed for UML modeling tool.  	Mouse select and rubberbanding size changes.  	Save a figure to a file. (Object serialization).  	Read a figure from a file. 	Connections that run only horizontally and vertically in segments.	Menu or palette of shapes with rubberbanding creation and connections.	Delete the selected figure and its connections via keyboard or otherwise. 	UNDO, REDO after some changes like deletes.  	Arrowheads of various shapes on connections. 	Textual equivalence (Text view) */