From 51f15b87614ef9d9a75735043fdb0acf268cd960 Mon Sep 17 00:00:00 2001 From: Graham Foster Date: Tue, 31 Oct 2017 13:05:43 -0700 Subject: [PATCH] Finished Lab 4 minus javadoc --- .../cs56/drawings/gmfoster/SimpleGui1.java | 34 ++++ .../gmfoster/advanced/AllMyDrawings.java | 149 ++++++++++++++++++ .../drawings/gmfoster/advanced/CoffeeCup.java | 85 ++++++++++ .../cs56/drawings/gmfoster/advanced/Fish.java | 39 +++++ .../gmfoster/advanced/FishWithFins.java | 37 +++++ .../drawings/gmfoster/advanced/House.java | 68 ++++++++ .../gmfoster/advanced/HouseWithWindows.java | 55 +++++++ .../advanced/MultiPictureComponent.java | 49 ++++++ .../gmfoster/advanced/MultiPictureViewer.java | 52 ++++++ .../gmfoster/advanced/WritePictureToFile.java | 83 ++++++++++ .../cs56/drawings/gmfoster/simple/Circle.java | 31 ++++ .../gmfoster/simple/PictureComponent.java | 106 +++++++++++++ .../gmfoster/simple/PictureViewer.java | 42 +++++ 13 files changed, 830 insertions(+) create mode 100644 src/edu/ucsb/cs56/drawings/gmfoster/SimpleGui1.java create mode 100755 src/edu/ucsb/cs56/drawings/gmfoster/advanced/AllMyDrawings.java create mode 100755 src/edu/ucsb/cs56/drawings/gmfoster/advanced/CoffeeCup.java create mode 100644 src/edu/ucsb/cs56/drawings/gmfoster/advanced/Fish.java create mode 100644 src/edu/ucsb/cs56/drawings/gmfoster/advanced/FishWithFins.java create mode 100755 src/edu/ucsb/cs56/drawings/gmfoster/advanced/House.java create mode 100755 src/edu/ucsb/cs56/drawings/gmfoster/advanced/HouseWithWindows.java create mode 100644 src/edu/ucsb/cs56/drawings/gmfoster/advanced/MultiPictureComponent.java create mode 100644 src/edu/ucsb/cs56/drawings/gmfoster/advanced/MultiPictureViewer.java create mode 100755 src/edu/ucsb/cs56/drawings/gmfoster/advanced/WritePictureToFile.java create mode 100644 src/edu/ucsb/cs56/drawings/gmfoster/simple/Circle.java create mode 100644 src/edu/ucsb/cs56/drawings/gmfoster/simple/PictureComponent.java create mode 100644 src/edu/ucsb/cs56/drawings/gmfoster/simple/PictureViewer.java diff --git a/src/edu/ucsb/cs56/drawings/gmfoster/SimpleGui1.java b/src/edu/ucsb/cs56/drawings/gmfoster/SimpleGui1.java new file mode 100644 index 00000000..89c7ea7f --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/gmfoster/SimpleGui1.java @@ -0,0 +1,34 @@ +package edu.ucsb.cs56.drawings.gmfoster; + +import javax.swing.*; + +/** SimpleGui1 comes from Head First Java 2nd Edition p. 355. + It illustrates a simple GUI with a Button that doesn't do anything yet. + + @author Head First Java, 2nd Edition p. 355 + @author P. Conrad (who only typed it in and added the Javadoc comments) + @author TODO: Add additional author here + @version CS56, Spring 2013, UCSB +*/ + +public class SimpleGui1 { + + /** main method to fire up a JFrame on the screen + @param args not used + */ + + public static void main (String[] args) { + JFrame frame = new JFrame() ; + + JButton button = new JButton("Click me and I'll give you some candy") ; + + java.awt.Color myColor = new java.awt.Color(103,240,100); // R, G, B values. + button.setBackground(myColor); + button.setOpaque(true); + + frame. setDefaultCloseOperation(JFrame. EXIT_ON_CLOSE) ; + frame. getContentPane() . add(button) ; + frame. setSize(300,300) ; + frame. setVisible(true) ; + } +} diff --git a/src/edu/ucsb/cs56/drawings/gmfoster/advanced/AllMyDrawings.java b/src/edu/ucsb/cs56/drawings/gmfoster/advanced/AllMyDrawings.java new file mode 100755 index 00000000..9ee7adc4 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/gmfoster/advanced/AllMyDrawings.java @@ -0,0 +1,149 @@ +package edu.ucsb.cs56.drawings.gmfoster.advanced; + +import java.awt.Graphics2D; +import java.awt.Shape; // general class for shapes +import java.awt.Color; // class for Colors +import java.awt.Stroke; +import java.awt.BasicStroke; + +import edu.ucsb.cs56.drawings.utilities.ShapeTransforms; +import edu.ucsb.cs56.drawings.utilities.GeneralPathWrapper; + +/** + * A class with static methods for drawing various pictures + * + * @author Phill Conrad + * @version for UCSB CS56, W16 + */ + +public class AllMyDrawings +{ + /** Draw a picture with a few fish + */ + + public static void drawPicture1(Graphics2D g2) { + + Fish h1 = new Fish(100,250,50,75); + g2.setColor(Color.CYAN); g2.draw(h1); + + // Make a blackl fish that's half the size, + // and moved over 150 pixels in x direction + + Shape h2 = ShapeTransforms.scaledCopyOfLL(h1,0.5,0.5); + h2 = ShapeTransforms.translatedCopyOf(h2,150,0); + g2.setColor(Color.BLACK); g2.draw(h2); + + // Here's a fish that's 4x as big (2x the original) + // and moved over 150 more pixels to right. + h2 = ShapeTransforms.scaledCopyOfLL(h2,4,4); + h2 = ShapeTransforms.translatedCopyOf(h2,150,0); + + // We'll draw this with a thicker stroke + Stroke thick = new BasicStroke (4.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL); + + // for hex colors, see (e.g.) http://en.wikipedia.org/wiki/List_of_colors + // #002FA7 is "International Klein Blue" according to Wikipedia + // In HTML we use #, but in Java (and C/C++) its 0x + + Stroke orig=g2.getStroke(); + g2.setStroke(thick); + g2.setColor(new Color(0x002FA7)); + g2.draw(h2); + + // Draw two fish with fins + + FishWithFins hw1 = new FishWithFins(50,350,40,75); + FishWithFins hw2 = new FishWithFins(200,350,200,100); + + g2.draw(hw1); + g2.setColor(new Color(0x8F00FF)); g2.draw(hw2); + + // @@@ FINALLY, SIGN AND LABEL YOUR DRAWING + + g2.setStroke(orig); + g2.setColor(Color.BLACK); + g2.drawString("A few fish by Graham Foster", 20,20); + } + + + /** Draw a picture with a few fish and coffee cups + */ + public static void drawPicture2(Graphics2D g2) { + + // Draw some coffee cups. + + CoffeeCup large = new CoffeeCup(100,50,225,150); + CoffeeCup smallCC = new CoffeeCup(20,50,40,30); + CoffeeCup tallSkinny = new CoffeeCup(20,150,20,40); + CoffeeCup shortFat = new CoffeeCup(20,250,40,20); + + g2.setColor(Color.RED); g2.draw(large); + g2.setColor(Color.GREEN); g2.draw(smallCC); + g2.setColor(Color.BLUE); g2.draw(tallSkinny); + g2.setColor(Color.MAGENTA); g2.draw(shortFat); + + Fish h1 = new Fish(100,250,50,75); + g2.setColor(Color.CYAN); g2.draw(h1); + + // Make a black fish that's half the size, + // and moved over 150 pixels in x direction + Shape h2 = ShapeTransforms.scaledCopyOfLL(h1,0.5,0.5); + h2 = ShapeTransforms.translatedCopyOf(h2,150,0); + g2.setColor(Color.BLACK); g2.draw(h2); + + // Here's a fish that's 4x as big (2x the original) + // and moved over 150 more pixels to right. + h2 = ShapeTransforms.scaledCopyOfLL(h2,4,4); + h2 = ShapeTransforms.translatedCopyOf(h2,150,0); + + // We'll draw this with a thicker stroke + Stroke thick = new BasicStroke (4.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL); + + // for hex colors, see (e.g.) http://en.wikipedia.org/wiki/List_of_colors + // #002FA7 is "International Klein Blue" according to Wikipedia + // In HTML we use #, but in Java (and C/C++) its 0x + + Stroke orig=g2.getStroke(); + g2.setStroke(thick); + g2.setColor(new Color(0x002FA7)); + g2.draw(h2); + + // Draw two fish with fins and bubbles + + FishWithFins hw1 = new FishWithFins(50,350,40,75); + FishWithFins hw2 = new FishWithFins(200,350,200,100); + + g2.draw(hw1); + g2.setColor(new Color(0x8F00FF)); + + // Rotate the second fish 45 degrees around its center. + Shape hw3 = ShapeTransforms.rotatedCopyOf(hw2, Math.PI/4.0); + + g2.draw(hw3); + + // @@@ FINALLY, SIGN AND LABEL YOUR DRAWING + + g2.setStroke(orig); + g2.setColor(Color.BLACK); + g2.drawString("A bunch of Coffee Cups and a few fish by Graham Foster", 20,20); + } + + + + public static void drawPicture3(Graphics2D g2) { + + // label the drawing + + g2.drawString("A bunch of Fish by Graham Foster", 20,20); + + + // Draw some coffee cups. + + Fish large = new Fish(100,50,225,150); + Fish small = new Fish(20,50,40,30); + + g2.setColor(Color.RED); g2.draw(large); + g2.setColor(Color.GREEN); g2.draw(small); + + } +} diff --git a/src/edu/ucsb/cs56/drawings/gmfoster/advanced/CoffeeCup.java b/src/edu/ucsb/cs56/drawings/gmfoster/advanced/CoffeeCup.java new file mode 100755 index 00000000..07125315 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/gmfoster/advanced/CoffeeCup.java @@ -0,0 +1,85 @@ +package edu.ucsb.cs56.drawings.gmfoster.advanced; +import java.awt.geom.GeneralPath; // combinations of lines and curves +import java.awt.Shape; // general class for shapes + +import edu.ucsb.cs56.drawings.utilities.ShapeTransforms; +import edu.ucsb.cs56.drawings.utilities.GeneralPathWrapper; + +/** + A Coffee Cup (wrapper around a General Path, implements Shape) + + This provides an example of how you can start with the coordinates + of a hard coded object, and end up with an object that can be + drawn anywhere, with any width or height. + + @author Phill Conrad + @version for CS56, W16, UCSB + +*/ +public class CoffeeCup extends GeneralPathWrapper implements Shape +{ + /** + * Constructor for objects of class CoffeeCup + */ + public CoffeeCup(double x, double y, double width, double height) + { + + // Specify the upper left corner, and the + // width and height of the original points used to + // plot the *hard-coded* coffee cup + + final double ORIG_ULX = 100.0; + final double ORIG_ULY = 100.0; + final double ORIG_HEIGHT = 300.0; + final double ORIG_WIDTH = 400.0; + + GeneralPath leftSide = new GeneralPath(); + + // left side of cup + + leftSide.moveTo(200,400); + leftSide.lineTo(160,360); + leftSide.lineTo(130,300); + leftSide.lineTo(100,200); + leftSide.lineTo(100,100); + + GeneralPath topAndBottom = new GeneralPath(); + + topAndBottom.moveTo(100,100); + topAndBottom.lineTo(500,100); // top of cup + + topAndBottom.moveTo(200,400); + topAndBottom.lineTo(400,400); // bottom of cup + + Shape rightSide = ShapeTransforms.horizontallyFlippedCopyOf(leftSide); + + // after flipping around the upper left hand corner of the + // bounding box, we move this over to the right by 400 pixels + + rightSide = ShapeTransforms.translatedCopyOf(rightSide, 400.0, 0.0); + + // now we put the whole thing together ino a single path. + + GeneralPath wholeCup = new GeneralPath (); + wholeCup.append(topAndBottom, false); + wholeCup.append(leftSide, false); + wholeCup.append(rightSide, false); + + // translate to the origin by subtracting the original upper left x and y + // then translate to (x,y) by adding x and y + + Shape s = ShapeTransforms.translatedCopyOf(wholeCup, -ORIG_ULX + x, -ORIG_ULY + y); + + // scale to correct height and width + s = ShapeTransforms.scaledCopyOf(s, + width/ORIG_WIDTH, + height/ORIG_HEIGHT) ; + + // Use the GeneralPath constructor that takes a shape and returns + // it as a general path to set our instance variable cup + + this.set(new GeneralPath(s)); + + } + +} diff --git a/src/edu/ucsb/cs56/drawings/gmfoster/advanced/Fish.java b/src/edu/ucsb/cs56/drawings/gmfoster/advanced/Fish.java new file mode 100644 index 00000000..8e97163e --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/gmfoster/advanced/Fish.java @@ -0,0 +1,39 @@ +package edu.ucsb.cs56.drawings.gmfoster.advanced; +import java.awt.geom.GeneralPath; +import java.awt.Shape; + +import java.awt.geom.Line2D; +import java.awt.geom.Rectangle2D; +import java.awt.geom.Ellipse2D; +import java.awt.geom.Path2D; + +import edu.ucsb.cs56.drawings.utilities.ShapeTransforms; +import edu.ucsb.cs56.drawings.utilities.GeneralPathWrapper; + + +public class Fish extends GeneralPathWrapper implements Shape +{ + + public Fish(double x, double y, double length, double height) + { + + GeneralPath tail = new GeneralPath(); + tail.moveTo(x,y); + tail.lineTo(x - .25*length ,y + .3*height); + tail.lineTo(x - .25*length ,y - .3*height); + tail.lineTo(x,y); + + GeneralPath body = new GeneralPath(); + body.moveTo(x + .7*length, y - .4*height); + body.lineTo(x,y); + body.lineTo(x + .7*length, y + .4*height); + + Ellipse2D.Double head = new Ellipse2D.Double(x + .4*length, y - .4* height, .8* length, .8* height); + + + GeneralPath wholeFish = this.get(); + wholeFish.append(tail, false); + wholeFish.append(body, false); + wholeFish.append(head, false); + } +} diff --git a/src/edu/ucsb/cs56/drawings/gmfoster/advanced/FishWithFins.java b/src/edu/ucsb/cs56/drawings/gmfoster/advanced/FishWithFins.java new file mode 100644 index 00000000..f928e372 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/gmfoster/advanced/FishWithFins.java @@ -0,0 +1,37 @@ +package edu.ucsb.cs56.drawings.gmfoster.advanced; +import java.awt.geom.GeneralPath; +import java.awt.Shape; +import java.awt.geom.Ellipse2D; + +public class FishWithFins extends Fish implements Shape +{ + public FishWithFins(double x, double y, double length, double height) + { + super(x,y,length,height); + + GeneralPath gp = this.get(); + + Ellipse2D.Double bub1 = + new Ellipse2D.Double(x + .4 * length, y - 1.2 * height, .1* length, .1 * length); + Ellipse2D.Double bub2 = + new Ellipse2D.Double(x + .6 * length, y -1.5 * height, .12 * length, .12 * length); + Ellipse2D.Double bub3 = + new Ellipse2D.Double(x, y - 1.8 * height, .08 * length, .08 * length); + + GeneralPath fin1 = new GeneralPath(); + fin1.moveTo(x + .2* length ,y); + fin1.lineTo(x + .4* length ,y); + fin1.lineTo(x + .3* length ,y + .3*height); + fin1.lineTo(x + .2* length ,y); + + Ellipse2D.Double eye = + new Ellipse2D.Double(x + length, y - .1 * height, .1 * length, .1 * length); + + GeneralPath wholeFish = this.get(); + wholeFish.append(bub1, false); + wholeFish.append(bub2, false); + wholeFish.append(bub3, false); + wholeFish.append(eye, false); + wholeFish.append(fin1, false); + } +} diff --git a/src/edu/ucsb/cs56/drawings/gmfoster/advanced/House.java b/src/edu/ucsb/cs56/drawings/gmfoster/advanced/House.java new file mode 100755 index 00000000..6e1976d4 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/gmfoster/advanced/House.java @@ -0,0 +1,68 @@ +package edu.ucsb.cs56.drawings.gmfoster.advanced; +import java.awt.geom.GeneralPath; // combinations of lines and curves +import java.awt.Shape; // general class for shapes + +import java.awt.geom.Line2D; +import java.awt.geom.Rectangle2D; + +import edu.ucsb.cs56.drawings.utilities.ShapeTransforms; +import edu.ucsb.cs56.drawings.utilities.GeneralPathWrapper; + +/** + A vector drawing of a house that implements + the Shape interface, and so can be drawn, as well as + rotated, scaled, etc. + + @author Phill Conrad + @version for CS56, W16, UCSB + +*/ +public class House extends GeneralPathWrapper implements Shape +{ + /** + Constructor + + @param x x coord of lower left corner of house + @param y y coord of lower left corner of house + @param width width of the house + @param height of house (including first story and second story) + */ + public House(double x, double y, double width, double height) + { + + // Rather than having to scale at the end, we can just + // draw things the right way to begin with, using the + // x, y, width and height. If you haven't already + // hard coded a particular drawing, this may be an easier + // way. + + double firstStoryHeight = .75 * height; + double roofHeight = height - firstStoryHeight; + + double firstStoryUpperLeftY = y + roofHeight; + + // Make the first story + + Rectangle2D.Double firstStory = + new Rectangle2D.Double(x, firstStoryUpperLeftY , + width, firstStoryHeight); + + // make the roof. Remember that y goes DOWN the page, + // so we ADD to y to get a "lower" value on the screen + + Line2D.Double leftRoof = + new Line2D.Double (x, y + roofHeight, + x + width/2.0, y); + + Line2D.Double rightRoof = + new Line2D.Double (x + width/2.0, y, + x + width, y + roofHeight); + + // put the whole house together + + GeneralPath wholeHouse = this.get(); + wholeHouse.append(firstStory, false); + wholeHouse.append(leftRoof, false); + wholeHouse.append(rightRoof, false); + } +} diff --git a/src/edu/ucsb/cs56/drawings/gmfoster/advanced/HouseWithWindows.java b/src/edu/ucsb/cs56/drawings/gmfoster/advanced/HouseWithWindows.java new file mode 100755 index 00000000..8bb565a3 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/gmfoster/advanced/HouseWithWindows.java @@ -0,0 +1,55 @@ +package edu.ucsb.cs56.drawings.gmfoster.advanced; +import java.awt.geom.GeneralPath; +import java.awt.Shape; +import java.awt.geom.Rectangle2D; + +/** + A House + + @author Phill Conrad + @version for CS56, W16, UCSB + +*/ +public class HouseWithWindows extends House implements Shape +{ + /** + * Constructor for objects of class CoffeeCup + */ + public HouseWithWindows(double x, double y, double width, double height) + { + // construct the basic house shell + super(x,y,width,height); + + // get the GeneralPath that we are going to append stuff to + GeneralPath gp = this.get(); + + // Make three windows, spaced like this, where w=width/10.0; + // | +--+ +--+ +--+ | + // | | | | | | | | + // | +--+ +--+ +--+ | + // |w 2w w 2w w w2 w| + // + // The top of window will be at y + 0.5*height and the + // height of the window is 0.25height; + + double w = 0.10 * width; + double winTop = y + 0.5 * height; + double winHt = 0.25 * height; + + Rectangle2D.Double win1 = + new Rectangle2D.Double(x + w, winTop, 2.0 * w, winHt); + Rectangle2D.Double win2 = + new Rectangle2D.Double(x + 4.0*w, winTop, 2.0 * w, winHt); + Rectangle2D.Double win3 = + new Rectangle2D.Double(x + 7.0*w, winTop, 2.0 * w, winHt); + + // add the windows to the house + // Look up the meaning of the second parameter of append + // (Hint--is a method of "GeneralPath") + + GeneralPath wholeHouse = this.get(); + wholeHouse.append(win1, false); + wholeHouse.append(win2, false); + wholeHouse.append(win3, false); + } +} diff --git a/src/edu/ucsb/cs56/drawings/gmfoster/advanced/MultiPictureComponent.java b/src/edu/ucsb/cs56/drawings/gmfoster/advanced/MultiPictureComponent.java new file mode 100644 index 00000000..557e4e5a --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/gmfoster/advanced/MultiPictureComponent.java @@ -0,0 +1,49 @@ +package edu.ucsb.cs56.drawings.gmfoster.advanced; + +import java.awt.Graphics; +import java.awt.Graphics2D; +import javax.swing.JComponent; + +/** + A component that draws a Picture by Phill Conrad + + @author Phill Conrad (original drawing) + @version CS56, W16, UCSB +*/ + + +public class MultiPictureComponent extends JComponent +{ + private int whichPicture = 0; + + public MultiPictureComponent(int whichPicture) { + this.whichPicture = whichPicture; + } + + /** The paintComponent method is always required if you want + * any graphics to appear in your JComponent. + * + * There is a paintComponent + * method that is created for you in the JComponent class, but it + * doesn't do what we want, so we have to "override" that method with + * our own method. + */ + + public void paintComponent(Graphics g) + { + Graphics2D g2 = (Graphics2D) g; + switch (this.whichPicture) { + case 1: + AllMyDrawings.drawPicture1(g2); + break; + case 2: + AllMyDrawings.drawPicture2(g2); + break; + case 3: + AllMyDrawings.drawPicture3(g2); + break; + default: + throw new IllegalArgumentException("Unknown value for whichPicture in MultiPictureComponent" + this.whichPicture); + } // switch + } // paintComponent +} diff --git a/src/edu/ucsb/cs56/drawings/gmfoster/advanced/MultiPictureViewer.java b/src/edu/ucsb/cs56/drawings/gmfoster/advanced/MultiPictureViewer.java new file mode 100644 index 00000000..8cb08d2d --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/gmfoster/advanced/MultiPictureViewer.java @@ -0,0 +1,52 @@ +package edu.ucsb.cs56.drawings.gmfoster.advanced; + +import javax.swing.JFrame; + +/** A viewer class to see a picture I drew with + * just three simple Java graphics objects, namely + * Rectangle, Line2D.Double, Ellipse2D.Double + * + * @author P. Conrad + * @version for UCSB CS56, W16 + */ + +public class MultiPictureViewer +{ + public static void main(String[] args) + { + int whichPicture = 1; + + // If user passed a command line argument, + // get which picture we want to display from the user + + if (args.length== 1) { + whichPicture = Integer.parseInt(args[0]); + } + + JFrame frame = new JFrame(); + + // Set the size to whatever size you like (width, height) + // For projects you turn in, lets not get any bigger than 640,480 + + frame.setSize(1000,1000); // @@@ MODIFY THIS LINE IF YOU LIKE + + // Set your own title + frame.setTitle("Graham's First Drawing"); // @@@ MODIFY THIS LINE + + // Always do this so that the red X (or red circle) works + // to close the window. + + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + // Instantiate your drawing as a "component" + + MultiPictureComponent component = + new MultiPictureComponent(whichPicture); + + // Always add your component to the frame + // and then make the window visible + + frame.add(component); + frame.setVisible(true); + } +} diff --git a/src/edu/ucsb/cs56/drawings/gmfoster/advanced/WritePictureToFile.java b/src/edu/ucsb/cs56/drawings/gmfoster/advanced/WritePictureToFile.java new file mode 100755 index 00000000..12754e84 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/gmfoster/advanced/WritePictureToFile.java @@ -0,0 +1,83 @@ +package edu.ucsb.cs56.drawings.gmfoster.advanced; + +import java.awt.image.BufferedImage; +import java.awt.Graphics2D; +import java.io.File; +import javax.imageio.ImageIO; +import java.io.IOException; + +/** + * A class with a main method that can write a drawing to a graphics file. + * + * @author P. Conrad, + * @version for CS56, W16, UCSB + */ + +public class WritePictureToFile +{ + public static void usage() + { + System.out.println("Usage: java WritePictureToFile whichImage mypic"); + // @@@ modify the next line to describe your picture + System.out.println(" whichImage should be 1,2 or 3"); + System.out.println(" whichImage chooses from drawPicture1, 2 or 3"); + System.out.println(" .png gets added to the filename"); + System.out.println(" e.g. if you pass mypic, filename is mypic.png"); + System.out.println("Example: java WritePictureToFile 3 foo"); + System.out.println(" produces foo.png from drawPicture3"); + } + + /** Write the chosen picture to a file. + * + * @param args command line arguments + */ + + public static void main(String[] args) + { + if (args.length != 2) { + usage(); + System.exit(1); + } + + String whichPicture = args[0]; // first command line arg is 1, 2, 3 + String outputfileName = args[1]; // second command line arg is which pic + + final int WIDTH = 640; + final int HEIGHT = 480; + + // create a new image + // TYPE_INT_ARGB is "RGB image" with transparency (A = alpha channel) + + BufferedImage bi = + new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_ARGB); + + Graphics2D g2 = bi.createGraphics(); + + if (whichPicture.equals("1")) { + AllMyDrawings.drawPicture1(g2); + } else if (whichPicture.equals("2")) { + AllMyDrawings.drawPicture2(g2); + } else if (whichPicture.equals("3")) { + AllMyDrawings.drawPicture3(g2); + } + + final String imageType = "png"; // choices: "gif", "png", "jpg" + + // We must declare this variable outside the try block, + // so we can see it inside the catch block + + String fullFileName = ""; + + try { + fullFileName = outputfileName + "." + imageType; + File outputfile = new File(fullFileName); + ImageIO.write(bi, imageType, outputfile); // actually writes file + System.out.println("I created " + fullFileName); // tell the user + } catch (IOException e) { + System.err.println("Sorry, an error occurred--I could not create " + + fullFileName + +"\n The error was: " + + e.toString()); + } + } +} diff --git a/src/edu/ucsb/cs56/drawings/gmfoster/simple/Circle.java b/src/edu/ucsb/cs56/drawings/gmfoster/simple/Circle.java new file mode 100644 index 00000000..587d8f11 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/gmfoster/simple/Circle.java @@ -0,0 +1,31 @@ +package edu.ucsb.cs56.drawings.gmfoster.simple; + +/** + * Circle extends Ellipse2D to make it easier to draw circles + * because the parameters to the constructor are more convenient + * + * @author P. Conrad + * @version CS56, W16, UCSB + */ + +public class Circle + extends java.awt.geom.Ellipse2D.Double + implements java.awt.Shape +{ + /** + * Constructor for objects of class Circle + * @param x x coordinate of center of circle + * @param y y coordinate of center of circle + * @param r radius of circle + */ + public Circle(double x, double y, double r) + { + // invoke the super class constructor, + // i.e. the one for Ellipse2D.Double, which takes + // upper-left-x, upper-left-y (of the bounding box) + // width, and height + + super( x - r, y - r, /* upper left corner of bounding box */ + r * 2, r * 2); /* width and height are double the radius */ + } +} diff --git a/src/edu/ucsb/cs56/drawings/gmfoster/simple/PictureComponent.java b/src/edu/ucsb/cs56/drawings/gmfoster/simple/PictureComponent.java new file mode 100644 index 00000000..a4b3e00b --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/gmfoster/simple/PictureComponent.java @@ -0,0 +1,106 @@ +package edu.ucsb.cs56.drawings.gmfoster.simple; + +import java.awt.Graphics; +import java.awt.Graphics2D; +import javax.swing.JComponent; + +// the four tools things we'll use to draw + +import java.awt.geom.Line2D; // single lines +import java.awt.geom.Rectangle2D; + +/** + A component that draws a Picture by Phill Conrad + + @author Phill Conrad (original drawing) + @author @@@ Graham Foster (fixed the snowmans's head) + @version for UCSB CS56, F17 +*/ + +// Your class should "extend JComponent +// This is "inheritance", which we'll start readina about in Chapter 10 +// It means that PictureComponent "is a" JComponent +// that is, a special type of JComponent that is for a specific purpose + +public class PictureComponent extends JComponent +{ + + /** The paintComponent method is always required if you want + * any graphics to appear in your JComponent. + * + * There is a paintComponent + * method that is created for you in the JComponent class, but it + * doesn't do what we want, so we have to "override" that method with + * our own method. + * + * This overriding is typical when inheritance is used. + * In inheritance, you take something that is a "basic" version of + * what you want, then you "trick it out" with your own custom features. + * Sort of a "pimp my Java class" kind of thing. + */ + + public void paintComponent(Graphics g) + { + // Recover Graphics2D--we always do this. + // See sections 2.12, p. 60-61 for an explanation + + Graphics2D g2 = (Graphics2D) g; + + // Now the fun part---we draw stuff! + // @@@ YOU'LL CUSTOMIZE EVERYTHING BELOW THIS LINE + + Rectangle2D.Double house = new Rectangle2D.Double(100, 200, 100, 100); + g2.draw( house); + + // lroof and rroof are the left and right sides of the roof, + Line2D.Double lroof = new Line2D.Double(100, 200, 150, 150); + Line2D.Double rroof = new Line2D.Double(150,150, 200,200); + + g2.draw(lroof); + g2.draw(rroof); + + // now a snowman: three circles + // here we use constants, so that if we want to change + // the dimensions later, or move the snowman around, + // it becomes easier. + + final double bottomRadius = 20; + final double middleRadius = 15; + final double topRadius = 10; + final double snowManCenterBottomX = 400; + final double snowManCenterBottomY = 300; + + Circle snowManBottomCircle = + new Circle + ( + snowManCenterBottomX, + snowManCenterBottomY - bottomRadius, + bottomRadius + ); + g2.draw(snowManBottomCircle); + + Circle snowManMiddleCircle = + new Circle + ( + snowManCenterBottomX, + snowManCenterBottomY - bottomRadius * 2 - middleRadius, + middleRadius + ); + g2.draw(snowManMiddleCircle); + + // @@@ ADD CODE HERE TO DRAW THE TOP CIRCLE + Circle snowManTopCircle = + new Circle + (snowManCenterBottomX, + snowManCenterBottomY - bottomRadius * 2 - middleRadius * 2 - topRadius, + topRadius); + g2.draw(snowManTopCircle); + + + // @@@ FINALLY, SIGN AND LABEL YOUR DRAWING + // @@@ 20, 20 are suggested coordinates, but you may change them + + g2.drawString("Graham Foster's Kickass Snowman", 20,20); + + } +} diff --git a/src/edu/ucsb/cs56/drawings/gmfoster/simple/PictureViewer.java b/src/edu/ucsb/cs56/drawings/gmfoster/simple/PictureViewer.java new file mode 100644 index 00000000..6fddbe3c --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/gmfoster/simple/PictureViewer.java @@ -0,0 +1,42 @@ +package edu.ucsb.cs56.drawings.gmfoster.simple; +import javax.swing.JFrame; + +/** A viewer class to see a picture I drew with + * just three simple Java graphics objects, namely + * Rectangle, Line2D.Double, Ellipse2D.Double + * + * @author P. Conrad + * @author ADD YOUR NAME @@@ + * @version CS56, W16, UCSB + */ + +public class PictureViewer +{ + public static void main(String[] args) + { + JFrame frame = new JFrame(); + + // Set the size to whatever size you like (width, height) + // For projects you turn in, lets not get any bigger than 640,480 + + frame.setSize(640,480); // @@@ MODIFY THIS LINE IF YOU LIKE + + // Set your own title + frame.setTitle("YOUR NAME HERE's Drawing"); // @@@ MODIFY THIS LINE + + // Always do this so that the red X (or red circle) works + // to close the window. + + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + // Instantiate your drawing as a "component" + + PictureComponent component = new PictureComponent(); + + // Always add your component to the frame + // and then make the window visible + + frame.add(component); + frame.setVisible(true); + } +}