Adding a new drawing library for Java

svn: r2008
This commit is contained in:
Kathy Gray 2006-01-27 22:16:14 +00:00
parent d950b675f2
commit dadb3ea6b5
27 changed files with 633 additions and 2 deletions

View File

@ -0,0 +1,11 @@
package graphics;
public class Black extends Color {
public String toString() { return "black"; }
public boolean equals(Object o) { return o instanceof Black; }
// public dynamic toScheme() { return rename.makeObj( mred.colorObj, 0, 0, 0); }
}

View File

@ -0,0 +1,11 @@
package graphics;
public class Blue extends Color {
public String toString() { return "blue"; }
public boolean equals(Object o) { return o instanceof Blue; }
// public dynamic toScheme() { return rename.makeObj( mred.colorObj, 0, 0, 0); }
}

View File

@ -0,0 +1,6 @@
package graphics;
public class Brown extends Color {
public String toString() { return "brown"; }
public boolean equals(Object o) { return o instanceof Brown; }
}

View File

@ -0,0 +1,4 @@
package graphics;
public abstract class Color {
}

View File

@ -0,0 +1,6 @@
package graphics;
public abstract class Command {
abstract void issue( dynamic canvas );
}

View File

@ -0,0 +1,9 @@
package graphics;
public abstract class CommandSequence {
abstract void drawAll(View v);
public CommandSequence reverse() {
return this.rev(new EmptySeq());
}
abstract CommandSequence rev(CommandSequence acc);
}

View File

@ -0,0 +1,20 @@
package graphics;
import scheme.lib.htdch.graphics.rename;
import scheme.lib.mred.mred;
public class DrawImage extends Command {
public Image i;
public Posn leftCorner;
public DrawImage( Image i, Posn left ) {
this.i = i;
this.leftCorner = left;
}
void issue(dynamic dc) {
dynamic bitmap = i.getBitmap();
dc.drawBitmap(bitmap, leftCorner.x, leftCorner.y, rename.toSymbol("solid"),
rename.newObject(mred.colorObj, "white"), bitmap.getLoadedMask());
}
}

View File

@ -0,0 +1,24 @@
package graphics;
import scheme.lib.htdch.graphics.rename;
public class DrawLine extends Command {
public Color color;
public Posn start;
public Posn stop;
public int width;
public DrawLine( Posn s, Posn e, int w, Color c ) {
this.color = c;
this.start = s;
this.stop = e;
this.width = w;
}
void issue( dynamic dc ) {
dc.setPen(color.toString(), width ,rename.toSymbol("solid"));
dc.drawLine( start.x,start.y,stop.x,stop.y);
}
}

View File

@ -0,0 +1,27 @@
package graphics;
import scheme.lib.htdch.graphics.rename;
public class DrawRectangle extends Command {
public Color color;
public Posn corner;
public int width;
public int height;
public String style;
public DrawRectangle( Posn corner, int w, int h, Color c, String style ) {
this.color = c;
this.width = w;
this.height = h;
this.style = style;
this.corner = corner;
}
void issue( dynamic dc ) {
dc.setPen(color.toString(), 1 ,rename.toSymbol("solid"));
dc.setBrush(color.toString(), rename.toSymbol(style));
dc.drawRectangle( corner.x,corner.y,width, height);
}
}

View File

@ -0,0 +1,9 @@
package graphics;
public class EmptySeq extends CommandSequence {
public EmptySeq() { }
void drawAll( View v) { }
CommandSequence rev( CommandSequence acc) {
return acc;
}
}

View File

@ -0,0 +1,100 @@
package graphics;
import scheme.lib.htdch.graphics.rename;
import scheme.lib.mred.mred;
public abstract class GameWorld extends World {
dynamic timer;
public GameWorld() {
super(new View());
}
public World transition( World last ){
if (!(last instanceof GameWorld))
throw new RuntimeException("Cannot transition from a non-GameWorld to a GameWorld");
this.display = last.display;
this.timer = ((GameWorld) last).timer;
return this;
}
public World endOfWorld() {
timer.stop();
return this;
}
World nextWorld = this;
//Produces a World that will animate with a clock tick of rate
public final boolean animate( int width, int height, int rate ) {
class TimerCallBack {
TimerCallBack() { }
public void callBack() {
World old = GameWorld.this.nextWorld;
GameWorld.this.nextWorld = GameWorld.this.nextWorld.onTick();
GameWorld.this.display.allowImage(false);
old.erase();
GameWorld.this.nextWorld.draw();
GameWorld.this.display.allowImage(true);
}
}
class KeyCallBack {
public void callBack(dynamic key) {
World old = GameWorld.this.nextWorld;
GameWorld.this.nextWorld = GameWorld.this.nextWorld.onKey(key);
GameWorld.this.display.allowImage(false);
old.erase();
GameWorld.this.nextWorld.draw();
GameWorld.this.display.allowImage(true);
}
}
display.display(width, height);
dynamic tCB = new TimerCallBack();
display.keyCallBack(rename.innerToFunction(1, new KeyCallBack()));
timer = rename.newObject(mred.timerObj, rename.innerToFunction(0,tCB));
timer.start(rate, false);
return true;
}
}
/* class TimerCallBack {
private World nextWorld;
TimerCallBack( World w) {
nextWorld = w;
}
public void callBack() {
rename.printer(nextWorld.toString());
nextWorld.erase();
nextWorld = nextWorld.onTick();
rename.printer(nextWorld.toString());
nextWorld.draw();
}
void updateNextWorld(World w) {
rename.printer("Calling update "+this.toString());
nextWorld = w;
}
}
class KeyCallBack {
private World nextWorld;
private TimerCallBack t;
KeyCallBack( World w, TimerCallBack t) {
nextWorld = w;
this.t = t;
}
public void callBack(dynamic key) {
rename.printer(key);
nextWorld = nextWorld.onKey(key);
rename.printer("Should call updateNextWorld next"+nextWorld.toString());
t.updateNextWorld(this.nextWorld);
}
}
*/

View File

@ -0,0 +1,6 @@
package graphics;
public class Green extends Color {
public String toString() { return "green"; }
public boolean equals(Object o) { return o instanceof Green;}
}

View File

@ -0,0 +1,63 @@
package graphics;
import scheme.lib.htdp.image;
import scheme.lib.graphics.graphics;
import scheme.lib.htdch.graphics.rename;
public class Image {
dynamic theImage;
Image( dynamic i ) {
this.theImage = i;
}
dynamic getBitmap() {
return theImage.getBitmap();
}
public Image movePinhole( Posn p ) {
return new Image( image.movePinhole(theImage, p.x, p.y) );
}
public Image putPinhole( Posn p ) {
return new Image( image.putPinhole(theImage, p.x, p.y) );
}
public Image overlay( Image i ) {
return new Image( image.overlay( theImage, i.theImage ) );
}
public Image overlayXY( Image i, Posn p) {
return new Image( rename.overlayXY( theImage, i.theImage, p.x, p.y));
}
public Posn getPinhole() {
return new Posn( image.pinholeX(theImage),image.pinholeY(theImage) );
}
public boolean inside( Image isInside ) {
return image.imageInsideP( theImage, isInside.theImage );
}
public Posn find( Image inside ) {
dynamic position = image.findImage(theImage, inside.theImage );
return new Posn( graphics.posnX(position), graphics.posnY(position) );
}
public Image addLine(Posn start, Posn end, Color c) {
return new Image(image.addLine(theImage, start.x, start.y, end.x, end.y, c.toString()));
}
public int width() {
return image.imageWidth( theImage );
}
public int height() {
return image.imageHeight( theImage );
}
public boolean equals(Object o) {
return (o instanceof Image) && rename.imageEqP(theImage,((Image) o).theImage);
}
}

View File

@ -0,0 +1,16 @@
package graphics;
public class LargerSeq extends CommandSequence {
Command first;
CommandSequence rest;
public LargerSeq(Command f, CommandSequence r) {
first = f; rest = r;
}
void drawAll( View v) {
v.drawToCanvas(first);
rest.drawAll(v);
}
CommandSequence rev( CommandSequence acc ) {
return rest.rev( new LargerSeq(first, acc));
}
}

View File

@ -0,0 +1,6 @@
package graphics;
public class Orange extends Color {
public String toString() { return "orange"; }
public boolean equals(Object o) { return o instanceof Orange; }
}

View File

@ -0,0 +1,38 @@
package graphics;
import scheme.lib.htdp.image;
import scheme.lib.htdch.graphics.rename;
public class PictureFactory {
boolean pinholeInCenter;
public PictureFactory( boolean pinholeInCenter ) {
this.pinholeInCenter = pinholeInCenter;
}
public Image makeCircle( int r, String mode, Color c) {
return new Image( image.circle( r, rename.toSymbol(mode), c.toString() ) );
}
public Image makeRectangle( int width, int height, String mode, Color c) {
return new Image( image.rectangle( width, height, rename.toSymbol(mode), c.toString() ));
}
public Image makeEllipse( int width, int height, String mode, Color c) {
return new Image( image.ellipse( width, height, rename.toSymbol(mode), c.toString() ));
}
public Image makeTriangle( int edge, String mode, Color c) {
return new Image( image.triangle( edge, rename.toSymbol(mode), c.toString() ));
}
public Image makeLine( Posn to, Color c) {
return new Image( image.line(to.x,to.y,c.toString()));
}
public Image makeText( String text, int ptSize, Color c) {
return new Image( image.text( text, ptSize, c.toString() ) );
}
}

View File

@ -0,0 +1,15 @@
package graphics;
public class Posn {
public int x;
public int y;
public Posn(int x, int y) {
this.x = x;
this.y = y;
}
public boolean equals(Object p) {
return p instanceof Posn && ((Posn) p).x==this.x && ((Posn) p).y == this.y;
}
}

View File

@ -0,0 +1,6 @@
package graphics;
public class Purple extends Color {
public String toString() { return "purple";}
public boolean equals(Object o) { return o instanceof Purple; }
}

View File

@ -0,0 +1,6 @@
package graphics;
public class Red extends Color {
public String toString() { return "red"; }
public boolean equals(Object o) { return o instanceof Red; }
}

View File

@ -0,0 +1,117 @@
package graphics;
import scheme.lib.mred.mred;
import scheme.lib.htdch.graphics.rename;
public class View {
private static int viewCount = 0;
private dynamic frame;
private dynamic canvas;
private dynamic dc;
private dynamic buffer;
private String name;
private boolean visible = false;
private boolean image = true;
public View() {
viewCount += 1;
this.name = "View-"+viewCount;
}
//Produces a View with a visible canvas of size x and y
public View display( int x, int y) {
if (visible)
this.hide();
buffer = rename.newObject(mred.bitmapDcObj, rename.newObject(mred.bitmapObj,x,y));
buffer.clear();
class CanvasInner {
public void callBack(dynamic canvas, dynamic dc) {
dc.drawBitmap( View.this.buffer.getBitmap(), 0,0);
}
}
frame = rename.newObject(mred.frameObj, name, false, x+15, y+20);
canvas = rename.newObject(rename.callBackCanvasObj, frame, rename.emptyList, rename.innerToFunction( 2, new CanvasInner()));
dc = canvas.getDc();
this.clear();
frame.show(true);
visible = true;
return this;
}
//Produces a View without a visible canvas
public View hide() {
this.visible = false;
frame.show(visible);
return this;
}
public View show() {
this.visible = true;
frame.show(visible);
return this;
}
//The Image is a equality testable version of the canvas after the drawing command
public Image draw( Command c) {
drawToCanvas(c);
dc.drawBitmap(buffer.getBitmap(), 0 ,0);
return getBufferCopy();
}
//The Image is again an equality testable version of the canvas after applying all commands
//Issues the commands in reverse order
public Image drawSequence( CommandSequence commands ) {
commands.drawAll(this);
dc.drawBitmap(buffer.getBitmap(), 0 ,0);
return getBufferCopy();
}
//Methods not seen by students
void allowImage( boolean ok ) {
this.image = ok;
}
private Image getBufferCopy() {
if (image) {
dynamic bufferBitmap = buffer.getBitmap();
dynamic bitmapCopy = rename.newObject(mred.bitmapObj, bufferBitmap.getWidth(), bufferBitmap.getHeight());
dynamic dcCopy = rename.newObject(mred.bitmapDcObj, bitmapCopy);
dcCopy.clear();
dcCopy.drawBitmap(bufferBitmap, 0, 0);
dcCopy.setBitmap(false);
return new Image(rename.newObject(mred.imageSnipObj, bitmapCopy, false));
} else {
return new Image(false);
}
}
void keyCallBack(dynamic curWorld) {
canvas.setCallback(curWorld);
}
//erases the canvas
void clear() {
buffer.clear();
dc.drawBitmap(buffer.getBitmap(), 0 ,0);
}
//Issues the drawing command in c, causing it to draw to the canvas
void drawToCanvas( Command c) {
if (!visible)
throw new RuntimeException("View must be displayed in order to draw in it");
c.issue(buffer);
}
}

View File

@ -0,0 +1,6 @@
package graphics;
public class White extends Color {
public String toString() { return "white"; }
public boolean equals(Object o) { return o instanceof White; }
}

View File

@ -0,0 +1,27 @@
package graphics;
public abstract class World {
public View display;
World(View v) {
display = v;
}
//Produce a World with the effects of receiving the given key
public abstract World onKey( String key );
//Produce a World with the effects of one clock tick passing
public abstract World onTick();
//Produces a World that will animate with a clock tick of rate
public abstract boolean animate( int width, int height, int rate );
public abstract World transition( World w);
public abstract Image draw();
public abstract Image erase();
}

View File

@ -0,0 +1,6 @@
package graphics;
public class Yellow extends Color {
public String toString() { return "yellow"; }
public boolean equals(Object o) { return o instanceof Yellow; }
}

View File

@ -0,0 +1,3 @@
(module info (lib "infotab.ss" "setup")
(define name "Java Graphics Teachpack")
(define install-collection "installer.ss"))

View File

@ -0,0 +1,39 @@
(module installer mzscheme
(require (lib "compile.ss" "profj"))
(provide installer)
(define (installer plthome)
(let ((draw-path (build-path (collection-path "htdch" "graphics"))))
(let ((javac
(lambda (file)
(parameterize ([current-load-relative-directory draw-path]
[current-directory draw-path])
(compile-java 'file 'file 'full
(build-path draw-path file)
#f #f)))))
(javac "Posn.java")
(javac "Color.java")
(javac "Image.djava")
(javac "PictureFactory.djava")
(javac "Black.java")
(javac "Blue.java")
(javac "Brown.java")
(javac "Green.java")
(javac "Orange.java")
(javac "Purple.java")
(javac "Red.java")
(javac "White.java")
(javac "Yellow.java")
(javac "Command.djava")
(javac "DrawLine.djava")
(javac "DrawRectangle.djava")
(javac "DrawImage.djava")
(javac "View.djava")
(javac "CommandSequence.java")
(javac "LargerSeq.java")
(javac "EmptySeq.java")
(javac "World.java")
(javac "GameWorld.djava")
)))
)

View File

@ -0,0 +1,49 @@
(module rename mzscheme
(require (lib "class.ss")
(lib "mred.ss" "mred")
(lib "image.ss" "htdp")
(lib "imageeq.ss" "lang" "private" ))
(provide to-symbol new-object call-back-canvas% overlay-x-y
inner->function image-eq? empty-list printer)
(define (inner->function num-args inner)
(cond
((= 0 num-args)
(lambda () (send inner call-back)))
((= 1 num-args)
(lambda (a) (send inner call-back a)))
((= 2 num-args)
(lambda (a b) (send inner call-back a b)))))
(define (printer s)
(printf "~a~n" s))
(define to-symbol string->symbol)
(define (new-object class . args)
((current-eval) #`(make-object #,class #,@args)))
(define empty-list null)
(define overlay-x-y overlay/xy)
(define image-eq? image=?)
(define call-back-canvas%
(class canvas%
(define call-back-proc (lambda (a) (void)))
(define/override (on-char char)
(call-back-proc (to-string char)))
(define/public (set-callback proc)
(set! call-back-proc proc))
(super-instantiate ())))
(define (to-string ke)
(let ((ke (send ke get-key-code)))
(if (char? ke) (string ke) (symbol->string ke))))
)

View File

@ -1,5 +1,6 @@
(module info (lib "infotab.ss" "setup")
(define name "htdch")
(define compile-subcollections (list (list "htdch" "draw")
))
)
(list "htdch" "graphics")
))
)