diff options
author | mkersten <mkersten> | 2003-11-10 19:11:18 +0000 |
---|---|---|
committer | mkersten <mkersten> | 2003-11-10 19:11:18 +0000 |
commit | ebfe0a1a9adfe64e41349167d4e3b5b188512d58 (patch) | |
tree | 188d7763530ed735b65875a302d5dfdd7ddcc7f4 /docs/teaching/demos/figures | |
parent | d54f21bbd778d29fd2cd1bdbe14402aa7a15551e (diff) | |
download | aspectj-ebfe0a1a9adfe64e41349167d4e3b5b188512d58.tar.gz aspectj-ebfe0a1a9adfe64e41349167d4e3b5b188512d58.zip |
Adding scrubbed demos (figures & spacewar), scripts, slides, and Eclipse project configurations.
Diffstat (limited to 'docs/teaching/demos/figures')
32 files changed, 1704 insertions, 0 deletions
diff --git a/docs/teaching/demos/figures/.classpath b/docs/teaching/demos/figures/.classpath new file mode 100644 index 000000000..8ae844dbf --- /dev/null +++ b/docs/teaching/demos/figures/.classpath @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" path="src"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> + <classpathentry kind="lib" path="C:/AspectJ-Demo/apps/eclipse-3.0/plugins/org.aspectj.ajde_1.1.4/aspectjrt.jar"/> + <classpathentry kind="output" path="bin"/> +</classpath> diff --git a/docs/teaching/demos/figures/.project b/docs/teaching/demos/figures/.project new file mode 100644 index 000000000..ccc6028ef --- /dev/null +++ b/docs/teaching/demos/figures/.project @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>figures</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.ajdt.ui.ajbuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.jdt.core.javanature</nature> + <nature>org.eclipse.ajdt.ui.ajnature</nature> + <nature>org.eclipse.ajdt.ui.ajnature</nature> + </natures> +</projectDescription> diff --git a/docs/teaching/demos/figures/build.xml b/docs/teaching/demos/figures/build.xml new file mode 100644 index 000000000..2816008dc --- /dev/null +++ b/docs/teaching/demos/figures/build.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" ?> +<!-- writen for Ant 1.5.1 --> +<project name="figures" default="reset"> + +<target name="reset" description="Reset the demonstration system sources"> + + <delete> + <fileset dir="src"/> + </delete> + <copy todir="src"> + <fileset dir="src-fresh"/> + </copy> +</target> + +</project>
\ No newline at end of file diff --git a/docs/teaching/demos/figures/readme.html b/docs/teaching/demos/figures/readme.html new file mode 100644 index 000000000..49e59396e --- /dev/null +++ b/docs/teaching/demos/figures/readme.html @@ -0,0 +1,299 @@ + +<head> +<style> +<!-- + table.MsoNormalTable + {mso-style-parent:""; + font-size:10.0pt; + font-family:"Times New Roman"; + } +--> +</style> +<STYLE TYPE="text/css"> +<!-- + + /* FOR THE SDA PAGE */ + + /* + BODY {margin-top: 15px; margin-left: 15px; margin-right: 15px;} + */ + + A:link { + color:#4756AC; + } + A:visited { + color:#60657B; + } + A:hover { + color:red + } + + INPUT {font:12px "Courier New", sans-serif;} + + H2 { + font:18px/18px Verdana, Arial, Helvetica, sans-serif; + color:black; + font-weight:bold; + margin-left: 10px; + line-height:110%; + } + H3 { + font:18px/18px Verdana, Arial, Helvetica, sans-serif; + color:black; + font-weight:bold; + margin-left: 10px; + line-height:110%; + } + H4 { + font:15px/16px Verdana, Arial, Helvetica, sans-serif; + color:black; + font-weight:bold; + margin-left: 10px; + line-height:140%; + } + P { + font:13px/13px Verdana, Arial, Helvetica, sans-serif; + margin-right: 10px; + margin-left: 10px; + line-height:130%; + } + .paragraph { + font:13px/13px Verdana, Arial, Helvetica, sans-serif; + margin-right: 10px; + margin-left: 10px; + line-height:130%; + } + .smallParagraph { + font:11px/11px Verdana, Arial, Helvetica, sans-serif; + margin-right: 10px; + margin-left: 10px; + line-height:130%; + } + LI { + font:13px/13px Verdana, Arial, Helvetica, sans-serif; + text-align:justify; + margin-right: 10px; + margin-left: 15px; + line-height:120%; + } + /* + UL { + font:13px/13px Verdana, Arial, Helvetica, sans-serif; + text-align:justify; + margin-right: 10px; + margin-left: 15px; + line-height:120%; + }*/ + + DL { + font:13px/13px Verdana, Arial, Helvetica, sans-serif; + text-align:justify; + margin-right: 10px; + margin-left: 15px; + line-height:120%; + } + B { font:13px/13px Verdana, Arial, Helvetica, sans-serif; + font-weight:bold; + line-height:140%; + } + .footer { + font:10px/10px Verdana, Arial, Helvetica, sans-serif; + color:#888888; + text-align:left + } + .figureTitle { + font:13px/13px Verdana, Arial, Helvetica, sans-serif; + text-align:justify; + text-align:center + } + .copyrightNotice { + font:10px/10px Verdana, Arial, Helvetica, sans-serif; + color:#999999; + line-height:110%; + } + .smallHeading { + font:13px/13px Verdana, Arial, Helvetica, sans-serif; + font-weight:bold; + line-height:110%; + } + .tinyHeading { + font:11px/11px Verdana, Arial, Helvetica, sans-serif; + font-weight:bold; + line-height:120%; + } + .newsText { + font:11px/11px Verdana, Arial, Helvetica, sans-serif; + line-height:130%; + } + .smallParagraph { + font:11px/11px Verdana, Arial, Helvetica, sans-serif; + line-height:130%; + } + .fancyHeading { + font:20px/20px Chantilly, Arial, Helvetica, sans-serif; + margin-right: 10px; + color:#6f7a92; + margin-left: 10px; + line-height:130%; + } + +--> +</STYLE> +</head> + +<h2 align="center">AspectJ Figures Demo Instructions</h2> +<h4>Setup</h4> +<ul> + <li> + <p style="text-align: left">src: contains the end result of the demo, with the Canvas.updateHistory() + call refactored into the src/figures/support/HistoryUpdating.aj aspect</li> + <li> + <p style="text-align: left">src-fresh: contains the plain Java sources that the demo starts with</li> +</ul> +<h4>Reset </h4> +<ul> + <li>run the "reset" target in build.xml to reset overwrite the sources in + src with those in src-fresh</li> +</ul> +<h4>Script</h4> +<div align="center"> + <table class="MsoNormalTable" border="0" cellspacing="3" cellpadding="0" style="width: 531.65pt; margin-left: -7.95pt" id="table1"> + <tr style="height: 33.45pt"> + <td style="width: 231px; height: 33.45pt; padding: 1.5pt; background: #F7F7F7"> + <p class="MsoNormal" style="text-indent: -.25in; margin-left: 40.5pt"> + <span style="font-size: 10.0pt; font-family: Symbol">·<span style="font:7.0pt "Times New Roman""> + </span></span><span style="font-size:10.0pt;font-family: + Tahoma">Show Figure editor running</span></p> + <p class="MsoNormal" style="text-indent: -.25in; margin-left: 40.5pt"> + <span style="font-size: 10.0pt; font-family: Symbol">·<span style="font:7.0pt "Times New Roman""> + </span></span><span style="font-size:10.0pt;font-family: + Tahoma">Inspect Point.java</span></p> + <p class="MsoNormal" style="text-indent: -.25in; margin-left: 40.5pt"> + <span style="font-size: 10.0pt; font-family: Symbol">·<span style="font:7.0pt "Times New Roman""> + </span></span><span style="font-size:10.0pt;font-family: + Tahoma">Use joinpoint probe or Eclipse search to find calls</span></td> + <td style="width: 461px; height: 33.45pt; padding: 1.5pt; background: #F7F7F7"> + <p class="MsoNormal" style="margin-left:7.5pt"> + <span style="font-family: Courier"><font size="1">call(void + figures.Canvas.updateHistory())</font></span></td> + </tr> + <tr style="height: 33.45pt"> + <td style="width: 231px; height: 33.45pt; padding: 1.5pt; background: #F7F7F7"> + <p class="MsoNormal" style="text-indent: -.25in; margin-left: 40.5pt"> + <span style="font-size: 10.0pt; font-family: Symbol">·<span style="font:7.0pt "Times New Roman""> + </span></span><span style="font-size:10.0pt;font-family: + Tahoma">Describe places that it’s called</span></p> + <p class="MsoNormal" style="text-indent: -.25in; margin-left: 40.5pt"> + <span style="font-size: 10.0pt; font-family: Symbol">·<span style="font:7.0pt "Times New Roman""> + </span></span><span style="font-size:10.0pt;font-family: + Tahoma">create aspect (defines a special class that can crosscut other + classes)</span></p> + <p class="MsoNormal" style="text-indent: -.25in; margin-left: 40.5pt"> + <span style="font-size: 10.0pt; font-family: Symbol">·<span style="font:7.0pt "Times New Roman""> + </span></span><span style="font-size:10.0pt;font-family: + Tahoma">aspect HistoryUpdating </span></p> + <p class="MsoNormal" style="text-indent: -.25in; margin-left: 40.5pt"> + <span style="font-size: 10.0pt; font-family: Symbol">·<span style="font:7.0pt "Times New Roman""> + </span></span><span style="font-size:10.0pt;font-family: + Tahoma">write pointcut (has name and parameters)</span></td> + <td style="width: 461px; height: 33.45pt; padding: 1.5pt; background: #F7F7F7"> + <p class="MsoNormal" style="margin-left:7.5pt"> + <span style="font-family: Courier"><font size="1">pointcut moves(): + </font> </span></p> + <p class="MsoNormal" style="margin-left:7.5pt"> + <span style="font-family: Courier"><font size="1"> execution(void + Line.setP1(Point)) || </font> </span></p> + <p class="MsoNormal" style="margin-left:7.5pt"> + <span style="font-family: Courier"><font size="1"> execution(void + Line.setP2(Point));</font></span></td> + </tr> + <tr style="height: 33.45pt"> + <td style="width: 231px; height: 33.45pt; padding: 1.5pt; background: #F7F7F7"> + <p class="MsoNormal" style="text-indent: -.25in; margin-left: 40.5pt"> + <span style="font-size: 10.0pt; font-family: Symbol">·<span style="font:7.0pt "Times New Roman""> + </span></span><span style="font-size:10.0pt;font-family: + Tahoma">write after advice (runs “on the way back out”)</span></td> + <td style="width: 461px; height: 33.45pt; padding: 1.5pt; background: #F7F7F7"> + <p class="MsoNormal" style="margin-left:7.5pt"> + <span style="font-family: Courier"><font size="1">after() returning: move() { <br> + <runs after each move> }</font></span></td> + </tr> + <tr style="height: 33.45pt"> + <td style="width: 231px; height: 33.45pt; padding: 1.5pt; background: #F7F7F7"> + <p class="MsoNormal" style="text-indent: -.25in; margin-left: 40.5pt"> + <span style="font-size: 10.0pt; font-family: Symbol">·<span style="font:7.0pt "Times New Roman""> + </span></span><span style="font-size:10.0pt;font-family: + Tahoma">extend advice to Point setters (multi-class)</span></td> + <td style="width: 461px; height: 33.45pt; padding: 1.5pt; background: #F7F7F7"> + <p class="MsoNormal" style="margin-left:7.5pt"> + <span style="font-family: Courier"><font size="1">call(void FigureElement+.set*(..))</font></span></td> + </tr> + <tr style="height: 33.45pt"> + <td style="width: 231px; height: 33.45pt; padding: 1.5pt; background: #F7F7F7"> + <p class="MsoNormal" style="text-indent: -.25in; margin-left: 40.5pt"> + <span style="font-size: 10.0pt; font-family: Symbol">·<span style="font:7.0pt "Times New Roman""> + </span></span><span style="font-size:10.0pt;font-family: + Tahoma">capture context & use interface</span></td> + <td style="width: 461px; height: 33.45pt; padding: 1.5pt; background: #F7F7F7"> + <p class="MsoNormal" style="margin-left:7.5pt"> + <span style="font-family: Courier"><font size="1">move(FigureElement fe): + this(fe) + &&..</font></span></td> + </tr> + <tr style="height: 33.45pt"> + <td style="width: 231px; height: 33.45pt; padding: 1.5pt; background: #F7F7F7"> + <p class="MsoNormal" style="text-indent: -.25in; margin-left: 40.5pt"> + <span style="font-size: 10.0pt; font-family: Symbol">·<span style="font:7.0pt "Times New Roman""> + </span></span><span style="font-size:10.0pt;font-family: + Tahoma">Show structure, note that SlothfulPoint is now included</span></p> + <p class="MsoNormal" style="text-indent: -.25in; margin-left: 40.5pt"> + <span style="font-size: 10.0pt; font-family: Symbol">·<span style="font:7.0pt "Times New Roman""> + </span></span><span style="font-size:10.0pt;font-family: + Tahoma">Run & show effect</span></td> + <td style="width: 461px; height: 33.45pt; padding: 1.5pt; background: #F7F7F7"> + <p class="MsoNormal" style="margin-left:7.5pt"> + <span style="font-family: Courier"><font size="1"> </font></span></td> + </tr> + <tr style="height: 33.45pt"> + <td style="width: 231px; height: 33.45pt; padding: 1.5pt; background: #F7F7F7"> + <p class="MsoNormal" style="text-indent: -.25in; margin-left: 40.5pt"> + <span style="font-size: 10.0pt; font-family: Symbol">·<span style="font:7.0pt "Times New Roman""> + </span></span><span style="font-size:10.0pt;font-family: + Tahoma">Show Point.moveBy history violoation</span></p> + <p class="MsoNormal" style="text-indent: -.25in; margin-left: 40.5pt"> + <span style="font-size: 10.0pt; font-family: Symbol">·<span style="font:7.0pt "Times New Roman""> + </span></span><span style="font-size:10.0pt;font-family: + Tahoma">Want to make sure that sets of private fields of classes implementing + FigureElement only happen from within the set methods</span></td> + <td style="width: 461px; height: 33.45pt; padding: 1.5pt; background: #F7F7F7"> + <p class="MsoNormal" style="margin-left:7.5pt"> + <span style="font-family: Courier"><font size="1">declare warning: + </font> </span></p> + <p class="MsoNormal" style="margin-left:7.5pt"> + <span style="font-family: Courier"><font size="1"> set(private * FigureElement+.*) <br> + && !(withincode(* + FigureElement+.set*(..)) || <br> + withincode(FigureElement+.new(..))):</font></span></p> + <p class="MsoNormal" style="margin-left:7.5pt"> + <span style="font-family: Courier"><font size="1"> "should only assign to fields + from set methods";</font></span></td> + </tr> + <tr style="height: 33.45pt"> + <td style="width: 231px; height: 33.45pt; padding: 1.5pt; background: #F7F7F7"> + <p class="MsoNormal" style="text-indent: -.25in; margin-left: 40.5pt"> + <span style="font-size: 10.0pt; font-family: Symbol">·<span style="font:7.0pt "Times New Roman""> + </span></span><span style="font-size:10.0pt;font-family: + Tahoma">Write before advice that does precondition checking on Points.</span></td> + <td style="width: 461px; height: 33.45pt; padding: 1.5pt; background: #F7F7F7"> + <p class="MsoNormal" style="margin-left:7.5pt"> + <span style="font-family:"Courier New""><font size="2">before(int</font><font size="2"> + newValue): <br> + set(int Point.*) && args(newValue) {<br> + if (newValue < 0) {<br> + throw new IAE("too small");<br> + } <br> + }</font></span></td> + </tr> + </table> +</div> +<p> </p> diff --git a/docs/teaching/demos/figures/scratch/HistoryUpdating.java b/docs/teaching/demos/figures/scratch/HistoryUpdating.java new file mode 100644 index 000000000..f4eff3d3f --- /dev/null +++ b/docs/teaching/demos/figures/scratch/HistoryUpdating.java @@ -0,0 +1,27 @@ +package figures.support; + +import figures.*; + +public aspect HistoryUpdating { + + pointcut moves(FigureElement fe): + this(fe) && + execution(void FigureElement+.set*(..)); + + after(FigureElement fe) returning: moves(fe) { + Canvas.updateHistory(fe); + } + + declare error: + set(private * FigureElement+.*) && + !(withincode(void FigureElement+.set*(..)) || + withincode(FigureElement+.new(..))): + "doh!!!"; + + before(int newValue): + set(int Point.*) && args(newValue) { + if (newValue < 0) { + throw new IllegalArgumentException("too small"); + } + } +} diff --git a/docs/teaching/demos/figures/src-fresh/figures/Box.java b/docs/teaching/demos/figures/src-fresh/figures/Box.java new file mode 100644 index 000000000..4db7f439d --- /dev/null +++ b/docs/teaching/demos/figures/src-fresh/figures/Box.java @@ -0,0 +1,55 @@ +/* +Copyright (c) 2002 Palo Alto Research Center Incorporated. All Rights Reserved. + */ + +package figures; + +import java.awt.*; +import java.awt.geom.*; + +public class Box extends ShapeFigureElement { + private Point _p0; + private Point _p1; + private Point _p2; + private Point _p3; + + public Box(int x0, int y0, int width, int height) { + _p0 = new Point(x0, y0); + _p1 = new Point(x0+width, y0); + _p2 = new Point(x0+width, y0+height); + _p3 = new Point(x0, y0+height); + } + + public Point getP0() { return _p0; } + public Point getP1() { return _p1; } + public Point getP2() { return _p2; } + public Point getP3() { return _p3; } + + public void move(int dx, int dy) { + _p0.move(dx, dy); + _p1.move(dx, dy); + _p2.move(dx, dy); + _p3.move(dx, dy); + } + + public void checkBoxness() { + if ((_p0.getX() == _p3.getX()) && + (_p1.getX() == _p2.getX()) && + (_p0.getY() == _p1.getY()) && + (_p2.getY() == _p3.getY())) + return; + throw new IllegalStateException("This is not a square."); + } + + public String toString() { + return "Box(" + _p0 + ", " + _p1 + ", " + _p2 + ", " + _p3 + ")"; + } + + public Shape getShape() { + return new Rectangle(getP1().getX(), + getP1().getY(), + getP3().getX() - getP1().getX(), + getP3().getY() - getP1().getY()); + } +} + diff --git a/docs/teaching/demos/figures/src-fresh/figures/Canvas.java b/docs/teaching/demos/figures/src-fresh/figures/Canvas.java new file mode 100644 index 000000000..ef849a5d5 --- /dev/null +++ b/docs/teaching/demos/figures/src-fresh/figures/Canvas.java @@ -0,0 +1,15 @@ +/* +Copyright (c) 2002 Palo Alto Research Center Incorporated. All Rights Reserved. + */ + +package figures; + +import figures.support.Log; + +public class Canvas { + public static void updateHistory() { } + + public static void updateHistory(FigureElement fe) { + System.out.println("> updating history for: " + fe); + } +} diff --git a/docs/teaching/demos/figures/src-fresh/figures/ColorControl.java b/docs/teaching/demos/figures/src-fresh/figures/ColorControl.java new file mode 100644 index 000000000..46d1ba428 --- /dev/null +++ b/docs/teaching/demos/figures/src-fresh/figures/ColorControl.java @@ -0,0 +1,20 @@ +/* +Copyright (c) 2002 Palo Alto Research Center Incorporated. All Rights Reserved. + */ + +package figures; + +import java.awt.Color; +import figures.FigureElement; + +public aspect ColorControl { + public static void setFillColor(FigureElement fe, Color color) { + // fill in here + } + + public static void setLineColor(FigureElement fe, Color color) { + // fill in here + } + + // fill in here +} diff --git a/docs/teaching/demos/figures/src-fresh/figures/FigureElement.java b/docs/teaching/demos/figures/src-fresh/figures/FigureElement.java new file mode 100644 index 000000000..ae06c132b --- /dev/null +++ b/docs/teaching/demos/figures/src-fresh/figures/FigureElement.java @@ -0,0 +1,21 @@ +/* +Copyright (c) 2001-2002 Palo Alto Research Center Incorporated. All Rights Reserved. + */ + +package figures; + +import java.awt.*; +import java.awt.geom.*; + +public interface FigureElement { + public static final int MIN_VALUE = 0; + public static final int MAX_VALUE = 500; + + public abstract void move(int dx, int dy); + + public abstract Rectangle getBounds(); + + public abstract boolean contains(Point2D p); + + public abstract void paint(Graphics2D g2); +} diff --git a/docs/teaching/demos/figures/src-fresh/figures/Group.java b/docs/teaching/demos/figures/src-fresh/figures/Group.java new file mode 100644 index 000000000..59c1a17cf --- /dev/null +++ b/docs/teaching/demos/figures/src-fresh/figures/Group.java @@ -0,0 +1,88 @@ +/* +Copyright (c) 2002 Palo Alto Research Center Incorporated. All Rights Reserved. + */ + +package figures; + +import java.util.*; +import java.awt.*; +import java.awt.geom.*; + +public class Group implements FigureElement { + private Collection _members; + private String _identifier; + + public Group(FigureElement first) { + this._members = new ArrayList(); + add(first); + } + + public void add(FigureElement fe) { + _members.add(fe); + } + + public Iterator members() { + return _members.iterator(); + } + + public void move(int dx, int dy) { + for (Iterator i = _members.iterator(); i.hasNext(); ) { + FigureElement fe = (FigureElement)i.next(); + fe.move(dx, dy); + } + } + + public void resetIdentifier(String identifier) { + resetIdentifier(identifier); + } + + public String toString() { + if (_identifier != null) { + return _identifier; + } + + StringBuffer buf = new StringBuffer("Group("); + for (Iterator i = _members.iterator(); i.hasNext(); ) { + buf.append(i.next().toString()); + if (i.hasNext()) { + buf.append(", "); + } + } + buf.append(")"); + return buf.toString(); + } + + public Rectangle getBounds() { + Rectangle previous = null; + for (Iterator i = _members.iterator(); i.hasNext(); ) { + FigureElement fe = (FigureElement)i.next(); + Rectangle rect = fe.getBounds(); + if (previous != null) { + previous = previous.union(rect); + } else { + previous = rect; + } + } + return previous; + } + + public boolean contains(Point2D p) { + for (Iterator i = _members.iterator(); i.hasNext(); ) { + FigureElement fe = (FigureElement)i.next(); + if (fe.contains(p)) return true; + } + return false; + } + + public void paint(Graphics2D g2) { + for (Iterator i = _members.iterator(); i.hasNext(); ) { + FigureElement fe = (FigureElement)i.next(); + fe.paint(g2); + } + } + + public int size() { + return _members.size(); + } +} + diff --git a/docs/teaching/demos/figures/src-fresh/figures/Line.java b/docs/teaching/demos/figures/src-fresh/figures/Line.java new file mode 100644 index 000000000..e76206639 --- /dev/null +++ b/docs/teaching/demos/figures/src-fresh/figures/Line.java @@ -0,0 +1,70 @@ +/* +Copyright (c) 2001-2002 Palo Alto Research Center Incorporated. All Rights Reserved. + */ + +package figures; + +import java.awt.*; +import java.awt.geom.*; + +public class Line extends ShapeFigureElement { + private Point _p1; + private Point _p2; + + public Line(Point p1, Point p2) { + _p1 = p1; + _p2 = p2; + } + + public Point getP1() { + return _p1; + } + + public void setP1(Point p1) { + _p1 = p1; + Canvas.updateHistory(); + } + + public Point getP2() { + return _p2; + } + + public void setP2(Point p2) { + _p2 = p2; + Canvas.updateHistory(); + } + + public void move(int dx, int dy) { + _p1.move(dx, dy); + _p2.move(dx, dy); + } + + public String toString() { + return "Line(" + _p1 + ", " + _p2 + ")"; + } + + /** + * Used to determine if this line {@link contains(Point2D)} a point. + */ + final static int THRESHHOLD = 5; + + /** + * Returns <code>true</code> if the point segment distance is less than + * {@link THRESHHOLD}. + */ + public boolean contains(Point2D p) { + return getLine2D().ptLineDist(p) < THRESHHOLD; + } + + private Line2D getLine2D() { + return new Line2D.Float((float)getP1().getX(), + (float)getP1().getY(), + (float)getP2().getX(), + (float)getP2().getY()); + } + + public Shape getShape() { + return getLine2D(); + } +} + diff --git a/docs/teaching/demos/figures/src-fresh/figures/Point.java b/docs/teaching/demos/figures/src-fresh/figures/Point.java new file mode 100644 index 000000000..9699aaf31 --- /dev/null +++ b/docs/teaching/demos/figures/src-fresh/figures/Point.java @@ -0,0 +1,59 @@ +/* +Copyright (c) 2001-2002 Palo Alto Research Center Incorporated. All Rights Reserved. + */ + +package figures; + +import java.awt.*; +import java.awt.geom.*; + +public class Point extends ShapeFigureElement { + private int _x; + private int _y; + + public Point(int x, int y) { + _x = x; + _y = y; + } + + public int getX() { + return _x; + } + + public void setX(int x) { + _x = x; + Canvas.updateHistory(); + } + + public int getY() { + return _y; + } + + public void setY(int y) { + _y = y; + Canvas.updateHistory(); + } + + public void move(int dx, int dy) { + _x += dx; + _y += dy; + } + + public String toString() { + return "Point(" + _x + ", " + _y + ")"; + } + + /** The height of displayed {@link Point}s. */ + private final static int HEIGHT = 10; + + /** The width of displayed {@link Point}s. -- same as {@link HEIGHT}. */ + private final static int WIDTH = Point.HEIGHT; + + public Shape getShape() { + return new Ellipse2D.Float((float)getX()-Point.WIDTH/2, + (float)getY()-Point.HEIGHT/2, + (float)Point.HEIGHT, + (float)Point.WIDTH); + } +} + diff --git a/docs/teaching/demos/figures/src-fresh/figures/ShapeFigureElement.java b/docs/teaching/demos/figures/src-fresh/figures/ShapeFigureElement.java new file mode 100644 index 000000000..29a4a89ad --- /dev/null +++ b/docs/teaching/demos/figures/src-fresh/figures/ShapeFigureElement.java @@ -0,0 +1,38 @@ +/* +Copyright (c) 2002 Palo Alto Research Center Incorporated. All Rights Reserved. + */ + +package figures; + +import java.awt.*; +import java.awt.geom.*; + +public abstract class ShapeFigureElement implements FigureElement { + public abstract void move(int dx, int dy); + + public abstract Shape getShape(); + + public Rectangle getBounds() { + return getShape().getBounds(); + } + + public boolean contains(Point2D p) { + return getShape().contains(p); + } + + public Color getLineColor() { + return Color.black; + } + + public Color getFillColor() { + return Color.red; + } + + public final void paint(Graphics2D g2) { + Shape shape = getShape(); + g2.setPaint(getFillColor()); + g2.fill(shape); + g2.setPaint(getLineColor()); + g2.draw(shape); + } +} diff --git a/docs/teaching/demos/figures/src-fresh/figures/SlothfulPoint.java b/docs/teaching/demos/figures/src-fresh/figures/SlothfulPoint.java new file mode 100644 index 000000000..620970373 --- /dev/null +++ b/docs/teaching/demos/figures/src-fresh/figures/SlothfulPoint.java @@ -0,0 +1,42 @@ +/* +Copyright (c) 2002 Palo Alto Research Center Incorporated. All Rights Reserved. + */ + +package figures; + +import java.awt.*; +import java.awt.geom.*; + +/** + * This class makes mistakes to be caught by invariant checkers. + */ +public class SlothfulPoint extends ShapeFigureElement { + private int _x; + private int _y; + + public SlothfulPoint(int x, int y) { + } + + public void setX(int x) { + _x = x; + } + + public void setY(int y) { + _y = y; + } + + public void move(int dx, int dy) { + setX(_x + dx); + setY(_y + dy); + } + + public String toString() { + return "SlothfulPoint"; + } + + public Shape getShape() { + return new Ellipse2D.Float((float)_x, + (float)_y, 1.0f, 1.0f); + } +} + diff --git a/docs/teaching/demos/figures/src-fresh/figures/gui/FigurePanel.java b/docs/teaching/demos/figures/src-fresh/figures/gui/FigurePanel.java new file mode 100644 index 000000000..cac59e835 --- /dev/null +++ b/docs/teaching/demos/figures/src-fresh/figures/gui/FigurePanel.java @@ -0,0 +1,172 @@ +/* +Copyright (c) 2001-2002 Palo Alto Research Center Incorporated. All Rights Reserved. + */ + +package figures.gui; + +import figures.Point; +import figures.Line; +import figures.FigureElement; +import figures.Group; + + +import java.awt.*; +import java.awt.geom.*; +import java.awt.event.*; +import java.io.*; +import java.util.*; +import javax.swing.*; +import javax.swing.text.*; +import javax.swing.border.*; + +public class FigurePanel extends JComponent { + + ButtonsPanel bp = new ButtonsPanel(); + FigureSurface fs = new FigureSurface(); + ConsolePanel cp = new ConsolePanel(); + + + public FigurePanel() { + setLayout(new BorderLayout()); + JPanel panel = new JPanel(); + panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); + panel.add(fs); + panel.add(bp); + JSplitPane sp = new JSplitPane(JSplitPane.VERTICAL_SPLIT, panel, cp); + sp.setPreferredSize(new Dimension(500, 400)); + sp.setDividerLocation(250); + add(BorderLayout.CENTER, sp); + } + + class ButtonsPanel extends JPanel { + private JLabel msgs = new JLabel("click to add a point or line"); + public ButtonsPanel() { + setLayout(new FlowLayout(FlowLayout.LEFT)); +// add(new JButton(new AbstractAction("Main") { +// public void actionPerformed(ActionEvent e) { +// Main.main(new String[]{}); +// fs.repaint(); +// } +// })); + add(msgs); + } + + public void log(String msg) { + msgs.setText(msg); + } + } + + static class ConsolePanel extends JPanel { + + JTextArea text = new JTextArea(); + + public ConsolePanel() { + super(new BorderLayout()); + text.setFont(StyleContext.getDefaultStyleContext().getFont("SansSerif", Font.PLAIN, 10)); + JScrollPane scroller = new JScrollPane(text); + scroller.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); + add(BorderLayout.CENTER, scroller); + } + + public void println(String msg) { + text.append(msg + '\n'); + } + } + + final static Color BACKGROUND = Color.white; + + static class FigureSurface extends JPanel implements MouseListener, MouseMotionListener { + private Group canvas; + + public FigureSurface() { + canvas = new Group(new Point(250, 250)); + addMouseMotionListener(this); + addMouseListener(this); + setPreferredSize(new Dimension(500,500)); + } + + private Point addPoint(int x, int y) { + Point p = new Point(x, y); + canvas.add(p); + repaint(); + return p; + } + + private Line addLine(Point p1, Point p2) { + if (Math.abs(p1.getX()-p2.getX()) < 5 || + Math.abs(p1.getY()-p2.getY()) < 5) { + return null; + } + + Line line = null; + if (p1 != null && p2 != null) { + line = new Line(p1, p2); + canvas.add(line); + } + repaint(); + return line; + } + + public void paint(Graphics g) { + Graphics2D g2 = (Graphics2D) g; + g2.setPaint(BACKGROUND); + g2.fill(new Rectangle2D.Float(0f, 0f, (float)g2.getClipBounds().width, (float)g2.getClipBounds().height)); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + canvas.paint(g2); + } + + + int lastX, lastY; + int pressX, pressY; + + FigureElement first = null; + Point point1 = null; + + public void mousePressed(MouseEvent e){ + int x = e.getX(), y = e.getY(); + pressX = lastX = x; pressY = lastY = y; + first = findFigureElement(x, y); + if (first == null) { + point1 = addPoint(x, y); + } + } + + public void mouseDragged(MouseEvent e) { + int x = e.getX(), y = e.getY(), dx = lastX-x, dy = lastY-y; + lastX = x; + lastY = y; + if (first == null) { + Line line = addLine(point1, new Point(x, y)); + if (line != null) { + canvas.add(line.getP2()); + first = line.getP2(); + canvas.add(line); + } + } else { + first.move(-dx, -dy); + } + repaint(); + } + + public void mouseReleased(MouseEvent e){ + mouseDragged(e); + first = null; + point1 = null; + } + + + public void mouseMoved(MouseEvent e){} + public void mouseClicked(MouseEvent e){} + public void mouseExited(MouseEvent e){} + public void mouseEntered(MouseEvent e){} + + private FigureElement findFigureElement(int x, int y) { + Point2D p = new Point2D.Float((float)x, (float)y); + for (Iterator i = canvas.members(); i.hasNext(); ) { + FigureElement fe = (FigureElement)i.next(); + if (fe.contains(p)) return fe; + } + return null; + } + } +} diff --git a/docs/teaching/demos/figures/src-fresh/figures/gui/LogAdapter.java b/docs/teaching/demos/figures/src-fresh/figures/gui/LogAdapter.java new file mode 100644 index 000000000..92a192f15 --- /dev/null +++ b/docs/teaching/demos/figures/src-fresh/figures/gui/LogAdapter.java @@ -0,0 +1,16 @@ +/* +Copyright (c) 2001-2002 Palo Alto Research Center Incorporated. All Rights Reserved. + */ + +package figures.gui; + +import figures.support.Log; + +aspect LogAdapter { + + before(String s): call(void Log.log(String)) && args(s) { + if (Main.panel != null) { + Main.panel.cp.println(s); + } + } +} diff --git a/docs/teaching/demos/figures/src-fresh/figures/gui/Main.java b/docs/teaching/demos/figures/src-fresh/figures/gui/Main.java new file mode 100644 index 000000000..da257aeda --- /dev/null +++ b/docs/teaching/demos/figures/src-fresh/figures/gui/Main.java @@ -0,0 +1,25 @@ +/* +Copyright (c) 2001-2002 Palo Alto Research Center Incorporated. All Rights Reserved. + */ + +package figures.gui; + +import javax.swing.*; +import figures.support.Log; +import figures.Point; + +public class Main { + static FigurePanel panel; + + public static void main(String[] args) { + JFrame figureFrame = new JFrame("Figure Editor"); + panel = new FigurePanel(); + figureFrame.setContentPane(panel); + figureFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + figureFrame.pack(); + figureFrame.setVisible(true); + +// Point p = new Point(0, 0); +// p.setX(-10); + } +} diff --git a/docs/teaching/demos/figures/src-fresh/figures/support/Log.java b/docs/teaching/demos/figures/src-fresh/figures/support/Log.java new file mode 100644 index 000000000..1ae18cc46 --- /dev/null +++ b/docs/teaching/demos/figures/src-fresh/figures/support/Log.java @@ -0,0 +1,36 @@ +/* +Copyright (c) 2002 Palo Alto Research Center Incorporated. All Rights Reserved. + */ + +package figures.support; + +public class Log { + private static StringBuffer data = new StringBuffer(); + + public static void traceObject(Object o) { + throw new UnsupportedOperationException(); + } + + public static void log(String s) { + data.append(s); + data.append(';'); + } + + public static void logClassName(Class _class) { + String name = _class.getName(); + int dot = name.lastIndexOf('.'); + if (dot == -1) { + log(name); + } else { + log(name.substring(dot+1, name.length())); + } + } + + public static String getString() { + return data.toString(); + } + + public static void clear() { + data.setLength(0); + } +} diff --git a/docs/teaching/demos/figures/src/figures/Box.java b/docs/teaching/demos/figures/src/figures/Box.java new file mode 100644 index 000000000..4db7f439d --- /dev/null +++ b/docs/teaching/demos/figures/src/figures/Box.java @@ -0,0 +1,55 @@ +/* +Copyright (c) 2002 Palo Alto Research Center Incorporated. All Rights Reserved. + */ + +package figures; + +import java.awt.*; +import java.awt.geom.*; + +public class Box extends ShapeFigureElement { + private Point _p0; + private Point _p1; + private Point _p2; + private Point _p3; + + public Box(int x0, int y0, int width, int height) { + _p0 = new Point(x0, y0); + _p1 = new Point(x0+width, y0); + _p2 = new Point(x0+width, y0+height); + _p3 = new Point(x0, y0+height); + } + + public Point getP0() { return _p0; } + public Point getP1() { return _p1; } + public Point getP2() { return _p2; } + public Point getP3() { return _p3; } + + public void move(int dx, int dy) { + _p0.move(dx, dy); + _p1.move(dx, dy); + _p2.move(dx, dy); + _p3.move(dx, dy); + } + + public void checkBoxness() { + if ((_p0.getX() == _p3.getX()) && + (_p1.getX() == _p2.getX()) && + (_p0.getY() == _p1.getY()) && + (_p2.getY() == _p3.getY())) + return; + throw new IllegalStateException("This is not a square."); + } + + public String toString() { + return "Box(" + _p0 + ", " + _p1 + ", " + _p2 + ", " + _p3 + ")"; + } + + public Shape getShape() { + return new Rectangle(getP1().getX(), + getP1().getY(), + getP3().getX() - getP1().getX(), + getP3().getY() - getP1().getY()); + } +} + diff --git a/docs/teaching/demos/figures/src/figures/Canvas.java b/docs/teaching/demos/figures/src/figures/Canvas.java new file mode 100644 index 000000000..ef849a5d5 --- /dev/null +++ b/docs/teaching/demos/figures/src/figures/Canvas.java @@ -0,0 +1,15 @@ +/* +Copyright (c) 2002 Palo Alto Research Center Incorporated. All Rights Reserved. + */ + +package figures; + +import figures.support.Log; + +public class Canvas { + public static void updateHistory() { } + + public static void updateHistory(FigureElement fe) { + System.out.println("> updating history for: " + fe); + } +} diff --git a/docs/teaching/demos/figures/src/figures/ColorControl.java b/docs/teaching/demos/figures/src/figures/ColorControl.java new file mode 100644 index 000000000..f1a76512b --- /dev/null +++ b/docs/teaching/demos/figures/src/figures/ColorControl.java @@ -0,0 +1,16 @@ +package figures; + +import java.awt.Color; +import figures.FigureElement; + +public aspect ColorControl { + public static void setFillColor(FigureElement fe, Color color) { + // fill in here + } + + public static void setLineColor(FigureElement fe, Color color) { + // fill in here + } + + // fill in here +} diff --git a/docs/teaching/demos/figures/src/figures/FigureElement.java b/docs/teaching/demos/figures/src/figures/FigureElement.java new file mode 100644 index 000000000..ae06c132b --- /dev/null +++ b/docs/teaching/demos/figures/src/figures/FigureElement.java @@ -0,0 +1,21 @@ +/* +Copyright (c) 2001-2002 Palo Alto Research Center Incorporated. All Rights Reserved. + */ + +package figures; + +import java.awt.*; +import java.awt.geom.*; + +public interface FigureElement { + public static final int MIN_VALUE = 0; + public static final int MAX_VALUE = 500; + + public abstract void move(int dx, int dy); + + public abstract Rectangle getBounds(); + + public abstract boolean contains(Point2D p); + + public abstract void paint(Graphics2D g2); +} diff --git a/docs/teaching/demos/figures/src/figures/Group.java b/docs/teaching/demos/figures/src/figures/Group.java new file mode 100644 index 000000000..59c1a17cf --- /dev/null +++ b/docs/teaching/demos/figures/src/figures/Group.java @@ -0,0 +1,88 @@ +/* +Copyright (c) 2002 Palo Alto Research Center Incorporated. All Rights Reserved. + */ + +package figures; + +import java.util.*; +import java.awt.*; +import java.awt.geom.*; + +public class Group implements FigureElement { + private Collection _members; + private String _identifier; + + public Group(FigureElement first) { + this._members = new ArrayList(); + add(first); + } + + public void add(FigureElement fe) { + _members.add(fe); + } + + public Iterator members() { + return _members.iterator(); + } + + public void move(int dx, int dy) { + for (Iterator i = _members.iterator(); i.hasNext(); ) { + FigureElement fe = (FigureElement)i.next(); + fe.move(dx, dy); + } + } + + public void resetIdentifier(String identifier) { + resetIdentifier(identifier); + } + + public String toString() { + if (_identifier != null) { + return _identifier; + } + + StringBuffer buf = new StringBuffer("Group("); + for (Iterator i = _members.iterator(); i.hasNext(); ) { + buf.append(i.next().toString()); + if (i.hasNext()) { + buf.append(", "); + } + } + buf.append(")"); + return buf.toString(); + } + + public Rectangle getBounds() { + Rectangle previous = null; + for (Iterator i = _members.iterator(); i.hasNext(); ) { + FigureElement fe = (FigureElement)i.next(); + Rectangle rect = fe.getBounds(); + if (previous != null) { + previous = previous.union(rect); + } else { + previous = rect; + } + } + return previous; + } + + public boolean contains(Point2D p) { + for (Iterator i = _members.iterator(); i.hasNext(); ) { + FigureElement fe = (FigureElement)i.next(); + if (fe.contains(p)) return true; + } + return false; + } + + public void paint(Graphics2D g2) { + for (Iterator i = _members.iterator(); i.hasNext(); ) { + FigureElement fe = (FigureElement)i.next(); + fe.paint(g2); + } + } + + public int size() { + return _members.size(); + } +} + diff --git a/docs/teaching/demos/figures/src/figures/Line.java b/docs/teaching/demos/figures/src/figures/Line.java new file mode 100644 index 000000000..e9911c6d7 --- /dev/null +++ b/docs/teaching/demos/figures/src/figures/Line.java @@ -0,0 +1,70 @@ +/* +Copyright (c) 2001-2002 Palo Alto Research Center Incorporated. All Rights Reserved. + */ + +package figures; + +import java.awt.*; +import java.awt.geom.*; + +public class Line extends ShapeFigureElement { + private Point _p1; + private Point _p2; + + public Line(Point p1, Point p2) { + _p1 = p1; + _p2 = p2; + } + + public Point getP1() { + return _p1; + } + + public void setP1(Point p1) { + _p1 = p1; +// Canvas.updateHistory(); + } + + public Point getP2() { + return _p2; + } + + public void setP2(Point p2) { + _p2 = p2; +// Canvas.updateHistory(); + } + + public void move(int dx, int dy) { + _p1.move(dx, dy); + _p2.move(dx, dy); + } + + public String toString() { + return "Line(" + _p1 + ", " + _p2 + ")"; + } + + /** + * Used to determine if this line {@link contains(Point2D)} a point. + */ + final static int THRESHHOLD = 5; + + /** + * Returns <code>true</code> if the point segment distance is less than + * {@link THRESHHOLD}. + */ + public boolean contains(Point2D p) { + return getLine2D().ptLineDist(p) < THRESHHOLD; + } + + private Line2D getLine2D() { + return new Line2D.Float((float)getP1().getX(), + (float)getP1().getY(), + (float)getP2().getX(), + (float)getP2().getY()); + } + + public Shape getShape() { + return getLine2D(); + } +} + diff --git a/docs/teaching/demos/figures/src/figures/Point.java b/docs/teaching/demos/figures/src/figures/Point.java new file mode 100644 index 000000000..d832b983c --- /dev/null +++ b/docs/teaching/demos/figures/src/figures/Point.java @@ -0,0 +1,59 @@ +/* +Copyright (c) 2001-2002 Palo Alto Research Center Incorporated. All Rights Reserved. + */ + +package figures; + +import java.awt.*; +import java.awt.geom.*; + +public class Point extends ShapeFigureElement { + private int _x; + private int _y; + + public Point(int x, int y) { + _x = x; + _y = y; + } + + public int getX() { + return _x; + } + + public void setX(int x) { + _x = x; +// Canvas.updateHistory(); + } + + public int getY() { + return _y; + } + + public void setY(int y) { + _y = y; +// Canvas.updateHistory(); + } + + public void move(int dx, int dy) { + setX(_x + dx); + setY(_y + dy); + } + + public String toString() { + return "Point(" + _x + ", " + _y + ")"; + } + + /** The height of displayed {@link Point}s. */ + private final static int HEIGHT = 10; + + /** The width of displayed {@link Point}s. -- same as {@link HEIGHT}. */ + private final static int WIDTH = Point.HEIGHT; + + public Shape getShape() { + return new Ellipse2D.Float((float)getX()-Point.WIDTH/2, + (float)getY()-Point.HEIGHT/2, + (float)Point.HEIGHT, + (float)Point.WIDTH); + } +} + diff --git a/docs/teaching/demos/figures/src/figures/ShapeFigureElement.java b/docs/teaching/demos/figures/src/figures/ShapeFigureElement.java new file mode 100644 index 000000000..29a4a89ad --- /dev/null +++ b/docs/teaching/demos/figures/src/figures/ShapeFigureElement.java @@ -0,0 +1,38 @@ +/* +Copyright (c) 2002 Palo Alto Research Center Incorporated. All Rights Reserved. + */ + +package figures; + +import java.awt.*; +import java.awt.geom.*; + +public abstract class ShapeFigureElement implements FigureElement { + public abstract void move(int dx, int dy); + + public abstract Shape getShape(); + + public Rectangle getBounds() { + return getShape().getBounds(); + } + + public boolean contains(Point2D p) { + return getShape().contains(p); + } + + public Color getLineColor() { + return Color.black; + } + + public Color getFillColor() { + return Color.red; + } + + public final void paint(Graphics2D g2) { + Shape shape = getShape(); + g2.setPaint(getFillColor()); + g2.fill(shape); + g2.setPaint(getLineColor()); + g2.draw(shape); + } +} diff --git a/docs/teaching/demos/figures/src/figures/SlothfulPoint.java b/docs/teaching/demos/figures/src/figures/SlothfulPoint.java new file mode 100644 index 000000000..620970373 --- /dev/null +++ b/docs/teaching/demos/figures/src/figures/SlothfulPoint.java @@ -0,0 +1,42 @@ +/* +Copyright (c) 2002 Palo Alto Research Center Incorporated. All Rights Reserved. + */ + +package figures; + +import java.awt.*; +import java.awt.geom.*; + +/** + * This class makes mistakes to be caught by invariant checkers. + */ +public class SlothfulPoint extends ShapeFigureElement { + private int _x; + private int _y; + + public SlothfulPoint(int x, int y) { + } + + public void setX(int x) { + _x = x; + } + + public void setY(int y) { + _y = y; + } + + public void move(int dx, int dy) { + setX(_x + dx); + setY(_y + dy); + } + + public String toString() { + return "SlothfulPoint"; + } + + public Shape getShape() { + return new Ellipse2D.Float((float)_x, + (float)_y, 1.0f, 1.0f); + } +} + diff --git a/docs/teaching/demos/figures/src/figures/gui/FigurePanel.java b/docs/teaching/demos/figures/src/figures/gui/FigurePanel.java new file mode 100644 index 000000000..cac59e835 --- /dev/null +++ b/docs/teaching/demos/figures/src/figures/gui/FigurePanel.java @@ -0,0 +1,172 @@ +/* +Copyright (c) 2001-2002 Palo Alto Research Center Incorporated. All Rights Reserved. + */ + +package figures.gui; + +import figures.Point; +import figures.Line; +import figures.FigureElement; +import figures.Group; + + +import java.awt.*; +import java.awt.geom.*; +import java.awt.event.*; +import java.io.*; +import java.util.*; +import javax.swing.*; +import javax.swing.text.*; +import javax.swing.border.*; + +public class FigurePanel extends JComponent { + + ButtonsPanel bp = new ButtonsPanel(); + FigureSurface fs = new FigureSurface(); + ConsolePanel cp = new ConsolePanel(); + + + public FigurePanel() { + setLayout(new BorderLayout()); + JPanel panel = new JPanel(); + panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); + panel.add(fs); + panel.add(bp); + JSplitPane sp = new JSplitPane(JSplitPane.VERTICAL_SPLIT, panel, cp); + sp.setPreferredSize(new Dimension(500, 400)); + sp.setDividerLocation(250); + add(BorderLayout.CENTER, sp); + } + + class ButtonsPanel extends JPanel { + private JLabel msgs = new JLabel("click to add a point or line"); + public ButtonsPanel() { + setLayout(new FlowLayout(FlowLayout.LEFT)); +// add(new JButton(new AbstractAction("Main") { +// public void actionPerformed(ActionEvent e) { +// Main.main(new String[]{}); +// fs.repaint(); +// } +// })); + add(msgs); + } + + public void log(String msg) { + msgs.setText(msg); + } + } + + static class ConsolePanel extends JPanel { + + JTextArea text = new JTextArea(); + + public ConsolePanel() { + super(new BorderLayout()); + text.setFont(StyleContext.getDefaultStyleContext().getFont("SansSerif", Font.PLAIN, 10)); + JScrollPane scroller = new JScrollPane(text); + scroller.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); + add(BorderLayout.CENTER, scroller); + } + + public void println(String msg) { + text.append(msg + '\n'); + } + } + + final static Color BACKGROUND = Color.white; + + static class FigureSurface extends JPanel implements MouseListener, MouseMotionListener { + private Group canvas; + + public FigureSurface() { + canvas = new Group(new Point(250, 250)); + addMouseMotionListener(this); + addMouseListener(this); + setPreferredSize(new Dimension(500,500)); + } + + private Point addPoint(int x, int y) { + Point p = new Point(x, y); + canvas.add(p); + repaint(); + return p; + } + + private Line addLine(Point p1, Point p2) { + if (Math.abs(p1.getX()-p2.getX()) < 5 || + Math.abs(p1.getY()-p2.getY()) < 5) { + return null; + } + + Line line = null; + if (p1 != null && p2 != null) { + line = new Line(p1, p2); + canvas.add(line); + } + repaint(); + return line; + } + + public void paint(Graphics g) { + Graphics2D g2 = (Graphics2D) g; + g2.setPaint(BACKGROUND); + g2.fill(new Rectangle2D.Float(0f, 0f, (float)g2.getClipBounds().width, (float)g2.getClipBounds().height)); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + canvas.paint(g2); + } + + + int lastX, lastY; + int pressX, pressY; + + FigureElement first = null; + Point point1 = null; + + public void mousePressed(MouseEvent e){ + int x = e.getX(), y = e.getY(); + pressX = lastX = x; pressY = lastY = y; + first = findFigureElement(x, y); + if (first == null) { + point1 = addPoint(x, y); + } + } + + public void mouseDragged(MouseEvent e) { + int x = e.getX(), y = e.getY(), dx = lastX-x, dy = lastY-y; + lastX = x; + lastY = y; + if (first == null) { + Line line = addLine(point1, new Point(x, y)); + if (line != null) { + canvas.add(line.getP2()); + first = line.getP2(); + canvas.add(line); + } + } else { + first.move(-dx, -dy); + } + repaint(); + } + + public void mouseReleased(MouseEvent e){ + mouseDragged(e); + first = null; + point1 = null; + } + + + public void mouseMoved(MouseEvent e){} + public void mouseClicked(MouseEvent e){} + public void mouseExited(MouseEvent e){} + public void mouseEntered(MouseEvent e){} + + private FigureElement findFigureElement(int x, int y) { + Point2D p = new Point2D.Float((float)x, (float)y); + for (Iterator i = canvas.members(); i.hasNext(); ) { + FigureElement fe = (FigureElement)i.next(); + if (fe.contains(p)) return fe; + } + return null; + } + } +} diff --git a/docs/teaching/demos/figures/src/figures/gui/LogAdapter.java b/docs/teaching/demos/figures/src/figures/gui/LogAdapter.java new file mode 100644 index 000000000..92a192f15 --- /dev/null +++ b/docs/teaching/demos/figures/src/figures/gui/LogAdapter.java @@ -0,0 +1,16 @@ +/* +Copyright (c) 2001-2002 Palo Alto Research Center Incorporated. All Rights Reserved. + */ + +package figures.gui; + +import figures.support.Log; + +aspect LogAdapter { + + before(String s): call(void Log.log(String)) && args(s) { + if (Main.panel != null) { + Main.panel.cp.println(s); + } + } +} diff --git a/docs/teaching/demos/figures/src/figures/gui/Main.java b/docs/teaching/demos/figures/src/figures/gui/Main.java new file mode 100644 index 000000000..d69f903e8 --- /dev/null +++ b/docs/teaching/demos/figures/src/figures/gui/Main.java @@ -0,0 +1,25 @@ +/* +Copyright (c) 2001-2002 Palo Alto Research Center Incorporated. All Rights Reserved. + */ + +package figures.gui; + +import javax.swing.*; +import figures.support.Log; +import figures.Point; + +public class Main { + static FigurePanel panel; + + public static void main(String[] args) { + JFrame figureFrame = new JFrame("Figure Editor"); + panel = new FigurePanel(); + figureFrame.setContentPane(panel); + figureFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + figureFrame.pack(); + figureFrame.setVisible(true); + + Point p = new Point(0, 0); + p.setX(-10); + } +} diff --git a/docs/teaching/demos/figures/src/figures/support/HistoryUpdating.aj b/docs/teaching/demos/figures/src/figures/support/HistoryUpdating.aj new file mode 100644 index 000000000..9699d032a --- /dev/null +++ b/docs/teaching/demos/figures/src/figures/support/HistoryUpdating.aj @@ -0,0 +1,27 @@ +package figures.support;
+
+import figures.*;
+
+public aspect HistoryUpdating {
+
+ pointcut moves(FigureElement fe):
+ this(fe) &&
+ execution(void FigureElement+.set*(..));
+
+ after(FigureElement fe) returning: moves(fe) {
+ Canvas.updateHistory(fe);
+ }
+
+ declare error:
+ set(private * FigureElement+.*) &&
+ !(withincode(void FigureElement+.set*(..)) ||
+ withincode(FigureElement+.new(..))):
+ "doh!!!";
+
+ before(int newValue):
+ set(int Point.*) && args(newValue) {
+ if (newValue < 0) {
+ throw new IllegalArgumentException("too small");
+ }
+ }
+}
diff --git a/docs/teaching/demos/figures/src/figures/support/Log.java b/docs/teaching/demos/figures/src/figures/support/Log.java new file mode 100644 index 000000000..1ae18cc46 --- /dev/null +++ b/docs/teaching/demos/figures/src/figures/support/Log.java @@ -0,0 +1,36 @@ +/* +Copyright (c) 2002 Palo Alto Research Center Incorporated. All Rights Reserved. + */ + +package figures.support; + +public class Log { + private static StringBuffer data = new StringBuffer(); + + public static void traceObject(Object o) { + throw new UnsupportedOperationException(); + } + + public static void log(String s) { + data.append(s); + data.append(';'); + } + + public static void logClassName(Class _class) { + String name = _class.getName(); + int dot = name.lastIndexOf('.'); + if (dot == -1) { + log(name); + } else { + log(name.substring(dot+1, name.length())); + } + } + + public static String getString() { + return data.toString(); + } + + public static void clear() { + data.setLength(0); + } +} |