diff --git a/.idea/ant.xml b/.idea/ant.xml new file mode 100644 index 00000000..a2a47698 --- /dev/null +++ b/.idea/ant.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 00000000..35eb1ddf --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/edu/ucsb/cs56/drawings/ckoziol/SimpleGui1.java b/src/edu/ucsb/cs56/drawings/ckoziol/SimpleGui1.java new file mode 100644 index 00000000..b293efca --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/ckoziol/SimpleGui1.java @@ -0,0 +1,38 @@ +package edu.ucsb.cs56.drawings.ckoziol; + +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 Chet Koziol + @version CS56, Fall 2016, 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,ee if this is working correctly") ; + + java.awt.Color myColor = new java.awt.Color(255,2,0); // R, G, B values. + + button.setBackground(myColor); + button.setOpaque(true); + + myColor = new java.awt.Color(200,200,200); + button.setForeground(myColor); + + 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/ckoziol/advanced/#HouseWithWindows.java# b/src/edu/ucsb/cs56/drawings/ckoziol/advanced/#HouseWithWindows.java# new file mode 100755 index 00000000..f6d4d86c --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/ckoziol/advanced/#HouseWithWindows.java# @@ -0,0 +1,55 @@ +package edu.ucsb.cs56.drawings.ckoziol.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 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/ckoziol/advanced/AllMyDrawings.java b/src/edu/ucsb/cs56/drawings/ckoziol/advanced/AllMyDrawings.java new file mode 100755 index 00000000..a64d9d1f --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/ckoziol/advanced/AllMyDrawings.java @@ -0,0 +1,79 @@ +package edu.ucsb.cs56.drawings.ckoziol.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 Chet Koziol + * @version for UCSB CS56, F16 + */ + +public class AllMyDrawings +{ + /** Draw a picture with a few houses + */ + + public static void drawPicture1(Graphics2D g2) { + + SmileyFace h1 = new SmileyFace(100,250,50); + g2.setColor(Color.BLACK); g2.draw(h1); + + SmileyFace h2 = new SmileyFace(300,300,10); + g2.setColor(Color.BLUE); g2.draw(h2); + + SmileyFace h3 = new SmileyFace(350,45,68); + g2.setColor(Color.ORANGE); g2.draw(h3); + + + g2.drawString("Smiley Face by Chet Koziol", 20,20); + } + + + public static void drawPicture2(Graphics2D g2) { + + SmileyFaceWithHat h1 = new SmileyFaceWithHat(100,250,50); + g2.setColor(Color.BLACK); g2.draw(h1); + + + SmileyFaceWithHat h2 = new SmileyFaceWithHat(300,300,25); + g2.setColor(Color.GREEN); g2.draw(h2); + + SmileyFaceWithHat h3 = new SmileyFaceWithHat(400, 400, 75); + Shape h4 = ShapeTransforms.rotatedCopyOf(h3, Math.PI/2.4); + g2.setColor(Color.RED); g2.draw(h4); + + SmileyFace h5 = new SmileyFace(300,50,10); + g2.setColor(Color.BLUE); g2.draw(h5); + + g2.drawString("Smiley Face With Hat by Chet Koziol", 20,20); + + } + + /** Draw a different picture with a few houses and coffee cups + */ + + public static void drawPicture3(Graphics2D g2) { + + // label the drawing + + g2.drawString("A bunch of Coffee Cups by Phill Conrad", 20,20); + + + // Draw some coffee cups. + + CoffeeCup large = new CoffeeCup(100,50,225,150); + CoffeeCup smallCC = new CoffeeCup(20,50,40,30); + + g2.setColor(Color.RED); g2.draw(large); + g2.setColor(Color.GREEN); g2.draw(smallCC); + + } +} diff --git a/src/edu/ucsb/cs56/drawings/ckoziol/advanced/Circle.java b/src/edu/ucsb/cs56/drawings/ckoziol/advanced/Circle.java new file mode 100644 index 00000000..d548855d --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/ckoziol/advanced/Circle.java @@ -0,0 +1,31 @@ +package edu.ucsb.cs56.drawings.ckoziol.advanced; + +/** + * 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/ckoziol/advanced/CoffeeCup.java b/src/edu/ucsb/cs56/drawings/ckoziol/advanced/CoffeeCup.java new file mode 100755 index 00000000..bcdd6f37 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/ckoziol/advanced/CoffeeCup.java @@ -0,0 +1,85 @@ +package edu.ucsb.cs56.drawings.ckoziol.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/ckoziol/advanced/House.java b/src/edu/ucsb/cs56/drawings/ckoziol/advanced/House.java new file mode 100755 index 00000000..cac5c3f9 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/ckoziol/advanced/House.java @@ -0,0 +1,68 @@ +package edu.ucsb.cs56.drawings.ckoziol.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/ckoziol/advanced/HouseWithWindows.java b/src/edu/ucsb/cs56/drawings/ckoziol/advanced/HouseWithWindows.java new file mode 100755 index 00000000..34edf041 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/ckoziol/advanced/HouseWithWindows.java @@ -0,0 +1,55 @@ +package edu.ucsb.cs56.drawings.ckoziol.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/ckoziol/advanced/MultiPictureComponent.java b/src/edu/ucsb/cs56/drawings/ckoziol/advanced/MultiPictureComponent.java new file mode 100644 index 00000000..7e1cbeb8 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/ckoziol/advanced/MultiPictureComponent.java @@ -0,0 +1,49 @@ +package edu.ucsb.cs56.drawings.ckoziol.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/ckoziol/advanced/MultiPictureViewer.java b/src/edu/ucsb/cs56/drawings/ckoziol/advanced/MultiPictureViewer.java new file mode 100644 index 00000000..c81b2709 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/ckoziol/advanced/MultiPictureViewer.java @@ -0,0 +1,52 @@ +package edu.ucsb.cs56.drawings.ckoziol.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(640,480); // @@@ MODIFY THIS LINE IF YOU LIKE + + // Set your own title + frame.setTitle("Chet Koziol's First Drawing"); + + // 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/ckoziol/advanced/SmileyFace.java b/src/edu/ucsb/cs56/drawings/ckoziol/advanced/SmileyFace.java new file mode 100755 index 00000000..24573461 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/ckoziol/advanced/SmileyFace.java @@ -0,0 +1,71 @@ +package edu.ucsb.cs56.drawings.ckoziol.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 Chet Koziol + @version for CS56, F16, UCSB + +*/ +public class SmileyFace extends GeneralPathWrapper implements Shape +{ + /** + Constructor + + @param x x coord of lower left corner of smiley face + @param y y coord of lower left corner of smiley face + @param radius radius of the smiley face + */ + public SmileyFace(double x, double y, double radius) + { + double eyeheight = y - radius/2.5; + double lefteyex = x - radius/3; + double righteyex = x + radius/3; + double eyesize = radius/6; + double smilesize = radius/4; + double leftsmile = x - radius/2; + // double rightsmile = x + radius/2; + double smileheight = y + radius/3.3; + + Circle head = new Circle (x,y,radius); + Circle lefteye = new Circle(lefteyex, eyeheight, eyesize); + Circle righteye = new Circle(righteyex, eyeheight, eyesize); + + GeneralPath smile = new GeneralPath(); + smile.moveTo(leftsmile, smileheight); + leftsmile += smilesize/2; + smileheight += smilesize/2; + smile.lineTo(leftsmile, smileheight); + leftsmile += smilesize/2; + smileheight += smilesize/3; + smile.lineTo(leftsmile, smileheight); + leftsmile += smilesize; + smile.lineTo(leftsmile, smileheight); + + + /** + The smile is made by drawing 3 lines making the left side of the smile, then copying that path, flipping it and moving it over to the right side to complete the smile + */ + Shape rightSide = ShapeTransforms.horizontallyFlippedCopyOf(smile); + rightSide = ShapeTransforms.translatedCopyOf(rightSide, 4*smilesize, 0.0); + + + GeneralPath wholeface = this.get(); + wholeface.append(smile, false); + wholeface.append(rightSide, false); + wholeface.append(head, false); + wholeface.append(lefteye, false); + wholeface.append(righteye, false); + + } +} diff --git a/src/edu/ucsb/cs56/drawings/ckoziol/advanced/SmileyFaceWithHat.java b/src/edu/ucsb/cs56/drawings/ckoziol/advanced/SmileyFaceWithHat.java new file mode 100755 index 00000000..4e23fdaf --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/ckoziol/advanced/SmileyFaceWithHat.java @@ -0,0 +1,40 @@ +package edu.ucsb.cs56.drawings.ckoziol.advanced; +import java.awt.geom.GeneralPath; +import java.awt.Shape; +import java.awt.geom.Rectangle2D; + +/** + A SmileyFace + + @author Chet Koziol + @version for CS56, F16, UCSB + +*/ +public class SmileyFaceWithHat extends SmileyFace implements Shape +{ + public SmileyFaceWithHat(double x, double y, double radius) + { + + /** + First create an instance of SmileyFace with the smileyface constructor, so we have a starting point on where to add the hat + */ + super(x,y,radius); + // get the GeneralPath that we are going to append stuff to + GeneralPath gp = this.get(); + + + /** + The hat is made add adding 2 rectangles on top of the head + */ + Rectangle2D.Double bottomHalfOfHat = + new Rectangle2D.Double(x-radius*1.3, y-radius-radius/3, radius*2.6, radius/3); + + Rectangle2D.Double topHalfOfHat = + new Rectangle2D.Double(x-radius/2, y-(radius*3), radius, 2*radius - radius/3); + + + GeneralPath wholeface = this.get(); + wholeface.append(bottomHalfOfHat, false); + wholeface.append(topHalfOfHat, false); + } +} diff --git a/src/edu/ucsb/cs56/drawings/ckoziol/advanced/WritePictureToFile.java b/src/edu/ucsb/cs56/drawings/ckoziol/advanced/WritePictureToFile.java new file mode 100755 index 00000000..3398c951 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/ckoziol/advanced/WritePictureToFile.java @@ -0,0 +1,83 @@ +package edu.ucsb.cs56.drawings.ckoziol.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/ckoziol/simple/Circle.java b/src/edu/ucsb/cs56/drawings/ckoziol/simple/Circle.java new file mode 100644 index 00000000..0edad887 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/ckoziol/simple/Circle.java @@ -0,0 +1,31 @@ +package edu.ucsb.cs56.drawings.ckoziol.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/ckoziol/simple/PictureComponent.java b/src/edu/ucsb/cs56/drawings/ckoziol/simple/PictureComponent.java new file mode 100644 index 00000000..2738fecc --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/ckoziol/simple/PictureComponent.java @@ -0,0 +1,108 @@ +package edu.ucsb.cs56.drawings.ckoziol.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 Chet Koziol + @version for UCSB CS56, F16 +*/ + +// 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("Chet Koziol's Snowman Drawing", 20,20); + + } +} diff --git a/src/edu/ucsb/cs56/drawings/ckoziol/simple/PictureViewer.java b/src/edu/ucsb/cs56/drawings/ckoziol/simple/PictureViewer.java new file mode 100644 index 00000000..af9ab3e0 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/ckoziol/simple/PictureViewer.java @@ -0,0 +1,42 @@ +package edu.ucsb.cs56.drawings.ckoziol.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("Chet Koziol'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); + } +} diff --git a/src/edu/ucsb/cs56/drawings/dkirby/SimpleGui1.java b/src/edu/ucsb/cs56/drawings/dkirby/SimpleGui1.java new file mode 100644 index 00000000..bf8aadec --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/dkirby/SimpleGui1.java @@ -0,0 +1,34 @@ +package edu.ucsb.cs56.drawings.dkirby; + +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 D. Kirby + @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 baby one more time") ; + + java.awt.Color myColor = new java.awt.Color(154,17,200); // 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/dkirby/advanced/AllMyDrawings.java b/src/edu/ucsb/cs56/drawings/dkirby/advanced/AllMyDrawings.java new file mode 100755 index 00000000..61b017ee --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/dkirby/advanced/AllMyDrawings.java @@ -0,0 +1,150 @@ +package edu.ucsb.cs56.drawings.dkirby.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 peanuts + */ + + public static void drawPicture1(Graphics2D g2) { + + Peanut p1 = new MrPeanut(250,250,50); + g2.setColor(Color.CYAN); g2.draw(p1); + + // Make a black house that's half the size, + // and moved over 150 pixels in x direction + + Shape p2 = ShapeTransforms.scaledCopyOfLL(p1,0.5,0.5); + p2 = ShapeTransforms.translatedCopyOf(p2,150,0); + g2.setColor(Color.BLACK); g2.draw(p2); + + // Here's a house that's 4x as big (2x the original) + // and moved over 150 more pixels to right. + p2 = ShapeTransforms.scaledCopyOfLL(p2,4,4); + p2 = ShapeTransforms.translatedCopyOf(p2,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(p2); + + // Draw two houses with Windows + + Peanut p3 = new MrPeanut(150,350,40); + Peanut p4 = new MrPeanut(200,350,200); + + g2.draw(p3); + g2.setColor(new Color(0x8F00FF)); g2.draw(p4); + + // @@@ FINALLY, SIGN AND LABEL YOUR DRAWING + + g2.setStroke(orig); + g2.setColor(Color.BLACK); + g2.drawString("A few MrPeanuts by Dominic Kirby", 20,20); + } + + + /** Draw a picture with a bunch of MrPeanuts + */ + public static void drawPicture2(Graphics2D g2) { + + // Draw some coffee cups. + + MrPeanut large = new MrPeanut(150,50,225); + MrPeanut smallMP = new MrPeanut(120,50,40); + MrPeanut tallSkinny = new MrPeanut(120,150,20); + MrPeanut shortFat = new MrPeanut(120,250,40); + + g2.setColor(Color.RED); g2.draw(large); + g2.setColor(Color.GREEN); g2.draw(smallMP); + g2.setColor(Color.BLUE); g2.draw(tallSkinny); + g2.setColor(Color.MAGENTA); g2.draw(shortFat); + + MrPeanut p1 = new MrPeanut(200,250,50); + g2.setColor(Color.CYAN); g2.draw(p1); + + // Make a black house that's half the size, + // and moved over 150 pixels in x direction + Shape p2 = ShapeTransforms.scaledCopyOfLL(p1,0.5,0.5); + p2 = ShapeTransforms.translatedCopyOf(p2,150,0); + g2.setColor(Color.BLACK); g2.draw(p2); + + // Here's a house that's 4x as big (2x the original) + // and moved over 150 more pixels to right. + p2 = ShapeTransforms.scaledCopyOfLL(p2,4,4); + p2 = ShapeTransforms.translatedCopyOf(p2,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(p2); + + // Draw two houses with Windows + + MrPeanut mp1 = new MrPeanut(150,350,40); + MrPeanut mp2 = new MrPeanut(250,350,200); + + g2.draw(mp1); + g2.setColor(new Color(0x8F00FF)); + + // Rotate the second house 45 degrees around its center. + Shape mp3 = ShapeTransforms.rotatedCopyOf(mp2, Math.PI/4.0); + + g2.draw(mp3); + + // @@@ FINALLY, SIGN AND LABEL YOUR DRAWING + + g2.setStroke(orig); + g2.setColor(Color.BLACK); + g2.drawString("A bunch of MrPeanuts by Dominic Kirby", 20,20); + } + + /** Draw a different picture with a few Mr Peanuts + */ + + public static void drawPicture3(Graphics2D g2) { + + // label the drawing + + g2.drawString("A bunch of MrPeanuts by Dominic Kirby", 20,20); + + + // Draw some coffee cups. + + MrPeanut large = new MrPeanut(150,50,225); + MrPeanut smallCC = new MrPeanut(120,50,40); + + g2.setColor(Color.RED); g2.draw(large); + g2.setColor(Color.GREEN); g2.draw(smallCC); + + } +} diff --git a/src/edu/ucsb/cs56/drawings/dkirby/advanced/CoffeeCup.java b/src/edu/ucsb/cs56/drawings/dkirby/advanced/CoffeeCup.java new file mode 100755 index 00000000..5015682e --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/dkirby/advanced/CoffeeCup.java @@ -0,0 +1,85 @@ +package edu.ucsb.cs56.drawings.dkirby.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/dkirby/advanced/House.java b/src/edu/ucsb/cs56/drawings/dkirby/advanced/House.java new file mode 100755 index 00000000..daa29923 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/dkirby/advanced/House.java @@ -0,0 +1,68 @@ +package edu.ucsb.cs56.drawings.dkirby.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/dkirby/advanced/HouseWithWindows.java b/src/edu/ucsb/cs56/drawings/dkirby/advanced/HouseWithWindows.java new file mode 100755 index 00000000..e4b2db82 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/dkirby/advanced/HouseWithWindows.java @@ -0,0 +1,55 @@ +package edu.ucsb.cs56.drawings.dkirby.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/dkirby/advanced/MrPeanut.java b/src/edu/ucsb/cs56/drawings/dkirby/advanced/MrPeanut.java new file mode 100644 index 00000000..4147b820 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/dkirby/advanced/MrPeanut.java @@ -0,0 +1,91 @@ +package edu.ucsb.cs56.drawings.dkirby.advanced; +import java.awt.geom.GeneralPath; // combinations of lines and curves +import java.awt.Shape; // general class for shapes +import java.awt.Graphics; +import java.awt.Color; +import java.awt.geom.Line2D; +import java.awt.geom.Rectangle2D; +import java.awt.geom.Ellipse2D.Double; +import java.awt.geom.Ellipse2D; +import java.awt.geom.RectangularShape; +import java.awt.Graphics2D; + +import edu.ucsb.cs56.drawings.utilities.ShapeTransforms; +import edu.ucsb.cs56.drawings.utilities.GeneralPathWrapper; + +/** + A Peanut with a top-hat, monocle, and arms/legs. + + @author Dominic Kirby + @version for CS56, W16, UCSB + +*/ +public class MrPeanut extends Peanut implements java.awt.Shape +{ + + + public MrPeanut(double x, double y, double height){ + super(x,y, height); + + GeneralPath gp = this.get(); + height = height * 2; + Rectangle2D.Double hatRidge = + new Rectangle2D.Double(x - height/4, y- height/20, height/5, + height/20); + + Rectangle2D.Double hatTop = + new Rectangle2D.Double(x-height/5, y - height/4, height/10, + height/5); + + Line2D.Double leftArmTop = + new Line2D.Double(x - height/4 , y + height/3, + x - 2*height/5, y + height/3); + + Line2D.Double leftArmBottom = + new Line2D.Double(x - 2* height/5 , y+ height/3, + x - 2*height/5 , y +height/2); + + Line2D.Double RightArmTop = + new Line2D.Double(x -height/16 , y + height/3, + x + height/10, y + height/3); + + Line2D.Double RightArmBottom = + new Line2D.Double(x + height/10, y + height/3, + x + height/10, y + height/2); + + Ellipse2D.Double monocle = + new Ellipse2D.Double(x - height/5-height/45 -height/70, + y + height/10-height/70, + height/15, height/15); + + Ellipse2D.Double LEye = + new Ellipse2D.Double(x - height/5-height/45, y + height/10, + height/30, height/30); + + Ellipse2D.Double REye = + new Ellipse2D.Double(x - height/8, y + height/10, + height/30, height/30); + + Line2D.Double leftLeg = + new Line2D.Double(x-height/4, y + 8*height/10, + x - height/5 -height/15, y + 5*height/4); + + Line2D.Double rightLeg = + new Line2D.Double(x-height/20, y + 8*height/10, + x-height/20, y + 5*height/4); + + GeneralPath MrPeanut = this.get(); + MrPeanut.append(hatRidge, false); + MrPeanut.append(hatTop, false); + MrPeanut.append(leftArmTop, false); + MrPeanut.append(leftArmBottom, false); + MrPeanut.append(RightArmTop, false); + MrPeanut.append(RightArmBottom, false); + MrPeanut.append(LEye, false); + MrPeanut.append(REye, false); + MrPeanut.append(monocle,false); + MrPeanut.append(leftLeg, false); + MrPeanut.append(rightLeg, false); + } +} + diff --git a/src/edu/ucsb/cs56/drawings/dkirby/advanced/MultiPictureComponent.java b/src/edu/ucsb/cs56/drawings/dkirby/advanced/MultiPictureComponent.java new file mode 100644 index 00000000..48b8cc97 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/dkirby/advanced/MultiPictureComponent.java @@ -0,0 +1,49 @@ +package edu.ucsb.cs56.drawings.dkirby.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/dkirby/advanced/MultiPictureViewer.java b/src/edu/ucsb/cs56/drawings/dkirby/advanced/MultiPictureViewer.java new file mode 100644 index 00000000..01340aed --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/dkirby/advanced/MultiPictureViewer.java @@ -0,0 +1,52 @@ +package edu.ucsb.cs56.drawings.dkirby.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(640,480); // @@@ MODIFY THIS LINE IF YOU LIKE + + // Set your own title + frame.setTitle("Dom'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/dkirby/advanced/Peanut.java b/src/edu/ucsb/cs56/drawings/dkirby/advanced/Peanut.java new file mode 100644 index 00000000..6b71d627 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/dkirby/advanced/Peanut.java @@ -0,0 +1,48 @@ +package edu.ucsb.cs56.drawings.dkirby.advanced; +import java.awt.geom.GeneralPath; // combinations of lines and curves +import java.awt.Shape; // general class for shapes +import java.awt.Graphics; +import java.awt.Color; +import java.awt.geom.Line2D; +import java.awt.geom.Rectangle2D; +import java.awt.geom.Ellipse2D.Double; +import java.awt.geom.Ellipse2D; +import java.awt.geom.RectangularShape; +import java.awt.Graphics2D; + +import edu.ucsb.cs56.drawings.utilities.ShapeTransforms; +import edu.ucsb.cs56.drawings.utilities.GeneralPathWrapper; + +/** + Two Ovals that when stacked, look mildy like a peanut + + @author Dominic Kirby + @version for CS56, W16, UCSB + +*/ + +public class Peanut extends GeneralPathWrapper implements java.awt.Shape +{ + /* + @param x x coord of the top of the peanut + @param radius, radius of the two bulges of the peanut + */ + public Peanut(double x, double y, double height){ + height = height*2; + Ellipse2D.Double top = + new Ellipse2D.Double(x-height/4,y,height/5, (height/2)); + + Ellipse2D.Double bottom = + new Ellipse2D.Double(x-height/4,y + height/2, + height/5, (height/2)); + + + GeneralPath wholePeanut = this.get(); + wholePeanut.append(top, false); + wholePeanut.append(bottom, false); + + + + + } +} diff --git a/src/edu/ucsb/cs56/drawings/dkirby/advanced/WritePictureToFile.java b/src/edu/ucsb/cs56/drawings/dkirby/advanced/WritePictureToFile.java new file mode 100755 index 00000000..e9b5a50f --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/dkirby/advanced/WritePictureToFile.java @@ -0,0 +1,83 @@ +package edu.ucsb.cs56.drawings.dkirby.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/dkirby/simple/Circle.java b/src/edu/ucsb/cs56/drawings/dkirby/simple/Circle.java new file mode 100644 index 00000000..fdd92dd4 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/dkirby/simple/Circle.java @@ -0,0 +1,31 @@ +package edu.ucsb.cs56.drawings.dkirby.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/dkirby/simple/PictureComponent.java b/src/edu/ucsb/cs56/drawings/dkirby/simple/PictureComponent.java new file mode 100644 index 00000000..2c391832 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/dkirby/simple/PictureComponent.java @@ -0,0 +1,110 @@ +package edu.ucsb.cs56.drawings.dkirby.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 @@@ Dominic Kirby(fixed the snowmans's head) + @version for UCSB CS56, W16 +*/ + +// 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 snowManHead = + new Circle( + snowManCenterBottomX, + snowManCenterBottomY - bottomRadius *2 - middleRadius * 2 - topRadius, + topRadius + ); + g2.draw(snowManHead); + + g2.drawString("Added Head Dkirby", 20,20); + + + // @@@ FINALLY, SIGN AND LABEL YOUR DRAWING + // @@@ 20, 20 are suggested coordinates, but you may change them + + // g2.drawString("Description and your name go here", 20,20); + + } +} diff --git a/src/edu/ucsb/cs56/drawings/dkirby/simple/PictureViewer.java b/src/edu/ucsb/cs56/drawings/dkirby/simple/PictureViewer.java new file mode 100644 index 00000000..06cc6917 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/dkirby/simple/PictureViewer.java @@ -0,0 +1,42 @@ +package edu.ucsb.cs56.drawings.dkirby.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("House on a hill"); // @@@ 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); + } +} diff --git a/src/edu/ucsb/cs56/drawings/hduransoto/SimpleGui1.java b/src/edu/ucsb/cs56/drawings/hduransoto/SimpleGui1.java new file mode 100644 index 00000000..e593be66 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/hduransoto/SimpleGui1.java @@ -0,0 +1,30 @@ +package edu.ucsb.cs56.drawings.hduransoto; + +import javax.swing.*; +/** + @author Head First Java, 2nd Edition p. 355 + @author P. Conrad (who only typed it in and added the Javadoc comments) + @author Hernan Duran Soto + @version CS56, Fall 2016, 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("Do Not Click Here!") ; + java.awt.Color myColor = new java.awt.Color(203,000,000); + + 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/hduransoto/advanced/#House.java# b/src/edu/ucsb/cs56/drawings/hduransoto/advanced/#House.java# new file mode 100755 index 00000000..6d99c1f9 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/hduransoto/advanced/#House.java# @@ -0,0 +1,70 @@ + +package edu.ucsb.cs56.drawings.hduransoto.advanced; +package edu.ucsb.cs56.drawings.hduransoto.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/hduransoto/advanced/AllMyDrawings.java b/src/edu/ucsb/cs56/drawings/hduransoto/advanced/AllMyDrawings.java new file mode 100755 index 00000000..0459faf0 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/hduransoto/advanced/AllMyDrawings.java @@ -0,0 +1,99 @@ +package edu.ucsb.cs56.drawings.hduransoto.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 Hernan Duran Soto + * @version for UCSB CS56, F16 + */ + +public class AllMyDrawings +{ + // Draw a picture with a few bears + public static void drawPicture1(Graphics2D g2) { + + Bear b1 = new Bear(100,250,50,75); + g2.setColor(new Color(0XC46210)); + g2.draw(b1); + + // Make a bear that's half the size, + // and moved over 150 pixels in x direction + + Shape b2 = ShapeTransforms.scaledCopyOfLL(b1,0.5,0.5); + b2 = ShapeTransforms.translatedCopyOf(b2,150,0); + g2.setColor(Color.BLACK); + g2.draw(b2); + + // Here's a bear that's 4x as big (2x the original) + // and moved over 150 more pixels to right & 170 down. + b2 = ShapeTransforms.scaledCopyOfLL(b2,4,4); + b2 = ShapeTransforms.translatedCopyOf(b2,150,170); + + // We'll draw this with a thicker stroke + Stroke thick = + new BasicStroke + (4.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL); + + Stroke orig=g2.getStroke(); + g2.setStroke(thick); + g2.setColor(new Color(0xA67B5B)); + g2.draw(b2); + + // SIGN AND LABEL + g2.setStroke(orig); + g2.setColor(Color.BLACK); + g2.drawString("bears", 20,20); + } + + + + public static void drawPicture2(Graphics2D g2) { + //make some panda bears + PandaBear big = new PandaBear(250,450,225,150); + PandaBear small = new PandaBear(220,250,40,30); + PandaBear tallSkinny = new PandaBear(220,350,20,40); + PandaBear shortFat = new PandaBear(350,250,40,20); + + g2.setColor(Color.BLACK); g2.draw(big); + g2.setColor(Color.BLACK); g2.draw(small); + g2.setColor(Color.BLACK); g2.draw(tallSkinny); + g2.setColor(Color.BLACK); g2.draw(shortFat); + + //SIGN AND LABEL + g2.setColor(Color.BLACK); + g2.drawString("A bunch of panda bears by Hernan Duran", 20,20); + } + + /** Draw a different picture with a bear and a panda bear + */ + + public static void drawPicture3(Graphics2D g2) { + + // label the drawing + g2.drawString("Drawing 3: A bunch of bears by Hernan Duran", 20,20); + + + // Draw all types of bears + Bear large = new Bear(500,400,75,150); + PandaBear small = new PandaBear(300,300,40,30); + Bear b3 = new Bear(150,400,50,200); + Shape b3Twin = ShapeTransforms.rotatedCopyOf(b3, Math.PI/-2.0); + PandaBear tiny = new PandaBear(150,100,10,10); + Shape tinyTwin = ShapeTransforms.rotatedCopyOf(tiny, Math.PI/-3.0); + + g2.setColor(new Color(0x964B00)); g2.draw(large); + g2.setColor(new Color(0x1B1B1B)); g2.draw(small); + g2.setColor(new Color(0xC2B280)); g2.draw(b3Twin); + g2.setColor(new Color(0x696969)); g2.draw(tinyTwin); + + } +} diff --git a/src/edu/ucsb/cs56/drawings/hduransoto/advanced/Bear.java b/src/edu/ucsb/cs56/drawings/hduransoto/advanced/Bear.java new file mode 100644 index 00000000..3a07e3b1 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/hduransoto/advanced/Bear.java @@ -0,0 +1,114 @@ +package edu.ucsb.cs56.drawings.hduransoto.advanced; + +import java.awt.Graphics; +import java.awt.Graphics2D; +import javax.swing.JComponent; +import java.awt.geom.GeneralPath; // combinations of lines and curves +import java.awt.Shape; +import java.awt.geom.Arc2D; +import java.awt.geom.Ellipse2D; +import edu.ucsb.cs56.drawings.utilities.ShapeTransforms; +import edu.ucsb.cs56.drawings.utilities.GeneralPathWrapper; + +public class Bear extends GeneralPathWrapper implements Shape{ + + public Bear + ( + double x, + double y, + double bellyRad, + double feetArmRad + ) + { + + double bellySize = bellyRad; + double headSize = bellySize * 0.8; + double feetArmSize = bellySize * 0.2; + + //make belly + Circle belly = + new Circle(x, y - bellySize, bellySize); + + //make head + Circle head = + new Circle + (x, y - bellySize * 2 - headSize, headSize); + + //make ears + Circle ear1 = + new Circle + (x+feetArmSize*1.5, y - bellySize*2-headSize*2.2, feetArmSize); + + Circle ear2 = + new Circle + (x-feetArmSize*1.5, y - bellySize*2 - headSize*2.2, feetArmSize); + + //make eyes + Circle eye1 = + new Circle + (x+feetArmSize*1.5, y - bellySize*2 - headSize*1.5, feetArmSize); + + Circle eye2 = + new Circle + (x-feetArmSize*1.5, y - bellySize*2 - headSize*1.5, feetArmSize); + + //make nose + Circle nose = + new Circle + (x, y - bellySize*2 - headSize, feetArmSize/2); + + //make mouth + Ellipse2D.Double mouth = + new Ellipse2D.Double + (x-feetArmSize*2, + y-bellySize*2-headSize/2, + feetArmSize*4, + feetArmSize); + + //make the feets + Ellipse2D.Double feet1 = + new Ellipse2D.Double + (x+feetArmSize*1.5, + y-bellySize*0.1, + feetArmSize*1.5, + feetArmSize*3); + + Ellipse2D.Double feet2 = + new Ellipse2D.Double + (x-feetArmSize*3, + y-bellySize*0.1, + feetArmSize*1.5, + feetArmSize*3); + + //make the arms + Ellipse2D.Double arm1 = + new Ellipse2D.Double + (x-headSize*1.45, + y-bellySize*2.1, + feetArmSize*3, + feetArmSize*2); + + Ellipse2D.Double arm2 = + new Ellipse2D.Double + (x+headSize*0.7, + y-bellySize*2.1, + feetArmSize*3, + feetArmSize*2); + + //put the bear together + GeneralPath Bear = this.get(); + Bear.append(belly, false); + Bear.append(head, false); + Bear.append(feet1, false); + Bear.append(feet2, false); + Bear.append(arm1, false); + Bear.append(arm2, false); + Bear.append(ear1, false); + Bear.append(ear2, false); + Bear.append(eye1, false); + Bear.append(eye2, false); + Bear.append(nose, false); + Bear.append(mouth, false); + } + +} diff --git a/src/edu/ucsb/cs56/drawings/hduransoto/advanced/Circle.java b/src/edu/ucsb/cs56/drawings/hduransoto/advanced/Circle.java new file mode 100644 index 00000000..f95c9dc0 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/hduransoto/advanced/Circle.java @@ -0,0 +1,32 @@ +package edu.ucsb.cs56.drawings.hduransoto.advanced; + + +/** + * 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/hduransoto/advanced/CoffeeCup.java b/src/edu/ucsb/cs56/drawings/hduransoto/advanced/CoffeeCup.java new file mode 100755 index 00000000..bf21574c --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/hduransoto/advanced/CoffeeCup.java @@ -0,0 +1,85 @@ +package edu.ucsb.cs56.drawings.hduransoto.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/hduransoto/advanced/House.java b/src/edu/ucsb/cs56/drawings/hduransoto/advanced/House.java new file mode 100755 index 00000000..5144bb88 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/hduransoto/advanced/House.java @@ -0,0 +1,68 @@ +package edu.ucsb.cs56.drawings.hduransoto.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/hduransoto/advanced/HouseWithWindows.java b/src/edu/ucsb/cs56/drawings/hduransoto/advanced/HouseWithWindows.java new file mode 100755 index 00000000..79379bd1 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/hduransoto/advanced/HouseWithWindows.java @@ -0,0 +1,55 @@ +package edu.ucsb.cs56.drawings.hduransoto.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/hduransoto/advanced/MultiPictureComponent.java b/src/edu/ucsb/cs56/drawings/hduransoto/advanced/MultiPictureComponent.java new file mode 100644 index 00000000..1b9e714f --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/hduransoto/advanced/MultiPictureComponent.java @@ -0,0 +1,49 @@ +package edu.ucsb.cs56.drawings.hduransoto.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/hduransoto/advanced/MultiPictureViewer.java b/src/edu/ucsb/cs56/drawings/hduransoto/advanced/MultiPictureViewer.java new file mode 100644 index 00000000..ba874b77 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/hduransoto/advanced/MultiPictureViewer.java @@ -0,0 +1,52 @@ +package edu.ucsb.cs56.drawings.hduransoto.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(640,480); // @@@ MODIFY THIS LINE IF YOU LIKE + + // Set your own title + frame.setTitle("Hernan'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/hduransoto/advanced/PandaBear.java b/src/edu/ucsb/cs56/drawings/hduransoto/advanced/PandaBear.java new file mode 100644 index 00000000..2bddec60 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/hduransoto/advanced/PandaBear.java @@ -0,0 +1,47 @@ +package edu.ucsb.cs56.drawings.hduransoto.advanced; +import java.awt.geom.GeneralPath; +import java.awt.Shape; +import java.awt.geom.Ellipse2D; + +/** + @author: Hernan Duran Soto + @term: CS56 F16 +*/ + +public class PandaBear extends Bear implements Shape +{ + + public PandaBear + ( + double x, + double y, + double bellyRad, + double feetArmRad + ) + { + super(x,y,bellyRad,feetArmRad); + double bellySize = bellyRad; + double headSize = bellySize * 0.8; + double feetArmSize = bellySize * 0.2; + GeneralPath gp = this.get(); + + //make the dark spot in the eye + Circle spotEye = + new Circle + (x+feetArmSize*1.5, + y-bellySize*2-headSize*1.5, + feetArmSize * 1.3); + + //make the dark spot in the belly + Ellipse2D.Double spotBelly = + new Ellipse2D.Double + (x-headSize*0.6, + y-bellySize*1.8, + bellySize, bellySize*1.7); + + //add all the new attributes to a panda bear + GeneralPath PandaBear = this.get(); + PandaBear.append(spotEye, false); + PandaBear.append(spotBelly, false); + } +} diff --git a/src/edu/ucsb/cs56/drawings/hduransoto/advanced/WritePictureToFile.java b/src/edu/ucsb/cs56/drawings/hduransoto/advanced/WritePictureToFile.java new file mode 100755 index 00000000..a1543f9a --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/hduransoto/advanced/WritePictureToFile.java @@ -0,0 +1,83 @@ +package edu.ucsb.cs56.drawings.hduransoto.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/hduransoto/simple/Circle.java b/src/edu/ucsb/cs56/drawings/hduransoto/simple/Circle.java new file mode 100644 index 00000000..b61764ee --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/hduransoto/simple/Circle.java @@ -0,0 +1,31 @@ +package edu.ucsb.cs56.drawings.hduransoto.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/hduransoto/simple/PictureComponent.java b/src/edu/ucsb/cs56/drawings/hduransoto/simple/PictureComponent.java new file mode 100644 index 00000000..756b59c6 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/hduransoto/simple/PictureComponent.java @@ -0,0 +1,108 @@ +package edu.ucsb.cs56.drawings.hduransoto.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 Hernan Duran Soto + @version for UCSB CS56, F16 +*/ + +// 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 * 4, + topRadius + ); + g2.draw(snowManTopCircle); + + // @@@ FINALLY, SIGN AND LABEL YOUR DRAWING + // @@@ 20, 20 are suggested coordinates, but you may change them + + g2.drawString("Snowman at my house - Hernan Duran Soto", 20,20); + + } +} diff --git a/src/edu/ucsb/cs56/drawings/hduransoto/simple/PictureViewer.java b/src/edu/ucsb/cs56/drawings/hduransoto/simple/PictureViewer.java new file mode 100644 index 00000000..1a76e367 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/hduransoto/simple/PictureViewer.java @@ -0,0 +1,42 @@ +package edu.ucsb.cs56.drawings.hduransoto.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 Hernan Duran Soto + * @version CS56, F16, 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("Snowman at my house - Hernan Duran Soto"); // @@@ 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); + } +} diff --git "a/src/edu/ucsb/cs56/drawings/pginty/Icon\r" "b/src/edu/ucsb/cs56/drawings/pginty/Icon\r" new file mode 100644 index 00000000..e69de29b diff --git a/src/edu/ucsb/cs56/drawings/pginty/SimpleGui1.java b/src/edu/ucsb/cs56/drawings/pginty/SimpleGui1.java new file mode 100644 index 00000000..94d5ebfe --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/pginty/SimpleGui1.java @@ -0,0 +1,34 @@ +package edu.ucsb.cs56.drawings.pginty; + +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 Peter Ginty + @version CS56, Fall 2016, 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... or don't") ; + + java.awt.Color myColor = new java.awt.Color(051,051,255); // 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/pginty/advanced/.DS_Store b/src/edu/ucsb/cs56/drawings/pginty/advanced/.DS_Store new file mode 100644 index 00000000..5008ddfc Binary files /dev/null and b/src/edu/ucsb/cs56/drawings/pginty/advanced/.DS_Store differ diff --git a/src/edu/ucsb/cs56/drawings/pginty/advanced/AllMyDrawings.java b/src/edu/ucsb/cs56/drawings/pginty/advanced/AllMyDrawings.java new file mode 100755 index 00000000..1ae39e6d --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/pginty/advanced/AllMyDrawings.java @@ -0,0 +1,121 @@ +package edu.ucsb.cs56.drawings.pginty.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; +import sun.security.provider.SHA; + +/** + * A class with static methods for drawing various pictures + * + * @author Phill Conrad + * @version for UCSB CS56, W16 + */ + +public class AllMyDrawings +{ + /** + * Demonstrates how buses can be used in a pattern. + * Alternates thick stroke buses with regular stroke buses + */ + + public static void drawPicture1(Graphics2D g2) { + // label the drawing + g2.setColor(Color.black); + g2.drawString("Alternating double-decker buses by Peter Ginty", 20,20); + + //save the normal stroke, create a thick stroke + Stroke normal = g2.getStroke(); + Stroke thick = new BasicStroke(4.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL); + + //create a double-decker bus + DoubleDeckerBus d1 = new DoubleDeckerBus(50, 150, 60, 50); + + //Shape used to hold transformations of the bus + Shape s1; + + //Repeat 3 times: draw a thick bus then a normal bus, incrementing the x coordinate each time + int xoffset = 0; + for (int i = 0; i < 3; ++i) { + s1 = ShapeTransforms.translatedCopyOf(d1, xoffset, 0); + g2.setStroke(thick); + g2.draw(s1); + xoffset += 80; + s1 = ShapeTransforms.translatedCopyOf(d1, xoffset, 0); + g2.setStroke(normal); + g2.draw(s1); + xoffset += 80; + + } + + } + + + /** + * Demonstrates Shape properties of Bus and DoubleDeckerBus objects. + * Creates new buses as translated, rotated, and resized copies. + */ + public static void drawPicture2(Graphics2D g2) { + // label the drawing + + g2.setColor(Color.black); + g2.drawString("Lots of double-decker buses by Peter Ginty", 20,20); + + // make a double-decker bus + + DoubleDeckerBus d1 = new DoubleDeckerBus(50, 300, 200, 150); + g2.draw(d1); + + //make another double-decker bus, half the size, and moved 225 pixels to the right + + Shape d2 = ShapeTransforms.scaledCopyOf(d1, 0.5, 0.5); + d2 = ShapeTransforms.translatedCopyOf(d2, 225, 0); + g2.draw(d2); + + //make another double-decker bus, this time rotated 180deg (upside-down) and translated vertically + + Shape d3 = ShapeTransforms.rotatedCopyOf(d2,Math.toRadians(180)); + d3 = ShapeTransforms.translatedCopyOf(d3, 0, 150); + g2.draw(d3); + + //make a normal bus, then create a larger bus around it (double dimensions) in a different color + + Bus b1 = new Bus(425, 150, 50, 50); + Shape b2 = ShapeTransforms.scaledCopyOf(b1, 2, 2); + g2.draw(b1); g2.setColor(Color.green); g2.draw(b2); + } + + /** + * Most simple example - declaring and drawing some buses and double-decker buses in different colors + */ + + public static void drawPicture3(Graphics2D g2) { + + // label the drawing + + g2.drawString("Some buses in different colors by Peter Ginty", 20,20); + + + // Draw some buses. + + Bus large = new Bus(50,250,300,150); + Bus little = new Bus(220,50,40,30); + + g2.setColor(Color.red); g2.draw(large); + g2.setColor(Color.green); g2.draw(little); + + //Draw some double decker buses. + + DoubleDeckerBus bigDouble = new DoubleDeckerBus(400, 300, 150, 150); + DoubleDeckerBus bigDouble2 = new DoubleDeckerBus(400, 450, 150, 150); + g2.setColor(Color.blue); g2.draw(bigDouble); + g2.setColor(Color.magenta); g2.draw(bigDouble2); + } + + +} diff --git a/src/edu/ucsb/cs56/drawings/pginty/advanced/Bus.java b/src/edu/ucsb/cs56/drawings/pginty/advanced/Bus.java new file mode 100644 index 00000000..1ca306cd --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/pginty/advanced/Bus.java @@ -0,0 +1,79 @@ +package edu.ucsb.cs56.drawings.pginty.advanced; + +import edu.ucsb.cs56.drawings.pginty.simple.Circle; +import edu.ucsb.cs56.drawings.utilities.GeneralPathWrapper; + +import java.awt.*; +import java.awt.geom.GeneralPath; +import java.awt.geom.Rectangle2D; + +/** + * A vector drawing of a Bus that implements Shape. + * It can be drawn, scaled, rotated, etc. + * + * @author pginty + * @version for CS56, W16, UCSB + */ + +public class Bus extends GeneralPathWrapper implements Shape { + + /** + * Constructor for a Bus + * @param x x coordinate of lower left corner of bus + * @param y y coordinate of lower left corner of bus + * @param width width of bus + * @param height height of bus + */ + public Bus (double x, double y, double width, double height) { + + double bodyHeight = 0.8 * height; + double bodyWidth = 0.92 * width; + + double frontHeight = 0.45 * height; + double frontWidth = 0.08 * width; + + double wheelRadius = (height - bodyHeight)/2; + + double windowSideLength = bodyWidth * 0.16; + + double bodyY = y - height; //bodyX=x + + double frontX = x + bodyWidth; + double frontY = y - wheelRadius * 2 - frontHeight; + + double wheel1CenterX = x + (bodyWidth/4); + double wheel2CenterX = x + (3*bodyWidth/4); + double wheelCenterY = y - wheelRadius; + + double windowY = bodyY + (bodyHeight/8); + double window1X = x + (bodyWidth/15); + double window2X = window1X + (bodyWidth/15) + windowSideLength; + double window3X = window2X + (bodyWidth/15) + windowSideLength; + double window4X = window3X + (bodyWidth/15) + windowSideLength; + + Rectangle2D.Double body = new Rectangle2D.Double(x, bodyY, bodyWidth, bodyHeight); + Rectangle2D.Double front = new Rectangle2D.Double(frontX, frontY, frontWidth, frontHeight); + + Rectangle2D.Double window1 = new Rectangle2D.Double(window1X, windowY, windowSideLength, windowSideLength); + Rectangle2D.Double window2 = new Rectangle2D.Double(window2X, windowY, windowSideLength, windowSideLength); + Rectangle2D.Double window3 = new Rectangle2D.Double(window3X, windowY, windowSideLength, windowSideLength); + Rectangle2D.Double window4 = new Rectangle2D.Double(window4X, windowY, windowSideLength, windowSideLength); + + Circle wheel1 = new Circle(wheel1CenterX, wheelCenterY, wheelRadius); + Circle wheel2 = new Circle(wheel2CenterX, wheelCenterY, wheelRadius); + + GeneralPath entireBus = this.get(); + + entireBus.append(body, false); + entireBus.append(front, false); + + entireBus.append(window1, false); + entireBus.append(window2, false); + entireBus.append(window3, false); + entireBus.append(window4, false); + + entireBus.append(wheel1, false); + entireBus.append(wheel2, false); + + } +} diff --git a/src/edu/ucsb/cs56/drawings/pginty/advanced/CoffeeCup.java b/src/edu/ucsb/cs56/drawings/pginty/advanced/CoffeeCup.java new file mode 100755 index 00000000..078eb0a3 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/pginty/advanced/CoffeeCup.java @@ -0,0 +1,85 @@ +package edu.ucsb.cs56.drawings.pginty.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/pginty/advanced/DoubleDeckerBus.java b/src/edu/ucsb/cs56/drawings/pginty/advanced/DoubleDeckerBus.java new file mode 100644 index 00000000..cd666566 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/pginty/advanced/DoubleDeckerBus.java @@ -0,0 +1,53 @@ +package edu.ucsb.cs56.drawings.pginty.advanced; + +import java.awt.*; +import java.awt.geom.GeneralPath; +import java.awt.geom.Rectangle2D; + +/** + * A type of bus that has two levels for passengers rather than one. + * It constructs a Bus in the lower half of the available area, and + * another level in the upper half. + * + * @author pginty + * @version for CS56, W16, UCSB + */ +public class DoubleDeckerBus extends Bus implements Shape{ + + /** + * Constructor for a DoubleDeckerBus + * @param x x coordinate of lower left corner of bus + * @param y y coordinate of lower left corner of bus + * @param width width of bus + * @param height height of bus + */ + public DoubleDeckerBus(double x, double y, double width, double height){ + super(x,y,width,height/2); //construct a bus in the lower half of the available window + GeneralPath doubleBus = this.get(); + + double bodyWidth = 0.92 * width; + + double windowSideLength = bodyWidth * .16; + + double secondLevelY = y - height; + + double windowY = secondLevelY + height/16; + double window1X = x + (bodyWidth/15); + double window2X = window1X + (bodyWidth/15) + windowSideLength; + double window3X = window2X + (bodyWidth/15) + windowSideLength; + double window4X = window3X + (bodyWidth/15) + windowSideLength; + + Rectangle2D.Double body = new Rectangle2D.Double(x, secondLevelY, bodyWidth, height/2); + + Rectangle2D.Double window1 = new Rectangle2D.Double(window1X, windowY, windowSideLength, windowSideLength); + Rectangle2D.Double window2 = new Rectangle2D.Double(window2X, windowY, windowSideLength, windowSideLength); + Rectangle2D.Double window3 = new Rectangle2D.Double(window3X, windowY, windowSideLength, windowSideLength); + Rectangle2D.Double window4 = new Rectangle2D.Double(window4X, windowY, windowSideLength, windowSideLength); + + doubleBus.append(body,false); + doubleBus.append(window1,false); + doubleBus.append(window2,false); + doubleBus.append(window3,false); + doubleBus.append(window4,false); + } +} diff --git a/src/edu/ucsb/cs56/drawings/pginty/advanced/House.java b/src/edu/ucsb/cs56/drawings/pginty/advanced/House.java new file mode 100755 index 00000000..8f44b642 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/pginty/advanced/House.java @@ -0,0 +1,68 @@ +package edu.ucsb.cs56.drawings.pginty.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/pginty/advanced/HouseWithWindows.java b/src/edu/ucsb/cs56/drawings/pginty/advanced/HouseWithWindows.java new file mode 100755 index 00000000..dbed41e5 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/pginty/advanced/HouseWithWindows.java @@ -0,0 +1,55 @@ +package edu.ucsb.cs56.drawings.pginty.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/pginty/advanced/Icon\r" "b/src/edu/ucsb/cs56/drawings/pginty/advanced/Icon\r" new file mode 100644 index 00000000..e69de29b diff --git a/src/edu/ucsb/cs56/drawings/pginty/advanced/MultiPictureComponent.java b/src/edu/ucsb/cs56/drawings/pginty/advanced/MultiPictureComponent.java new file mode 100644 index 00000000..c4fdbc2f --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/pginty/advanced/MultiPictureComponent.java @@ -0,0 +1,49 @@ +package edu.ucsb.cs56.drawings.pginty.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/pginty/advanced/MultiPictureViewer.java b/src/edu/ucsb/cs56/drawings/pginty/advanced/MultiPictureViewer.java new file mode 100644 index 00000000..3878dc07 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/pginty/advanced/MultiPictureViewer.java @@ -0,0 +1,52 @@ +package edu.ucsb.cs56.drawings.pginty.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(640,480); // @@@ MODIFY THIS LINE IF YOU LIKE + + // Set your own title + frame.setTitle("Phill'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/pginty/advanced/WritePictureToFile.java b/src/edu/ucsb/cs56/drawings/pginty/advanced/WritePictureToFile.java new file mode 100755 index 00000000..88346178 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/pginty/advanced/WritePictureToFile.java @@ -0,0 +1,83 @@ +package edu.ucsb.cs56.drawings.pginty.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/pginty/simple/Circle.java b/src/edu/ucsb/cs56/drawings/pginty/simple/Circle.java new file mode 100644 index 00000000..86959133 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/pginty/simple/Circle.java @@ -0,0 +1,31 @@ +package edu.ucsb.cs56.drawings.pginty.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/pginty/simple/Icon\r" "b/src/edu/ucsb/cs56/drawings/pginty/simple/Icon\r" new file mode 100644 index 00000000..e69de29b diff --git a/src/edu/ucsb/cs56/drawings/pginty/simple/PictureComponent.java b/src/edu/ucsb/cs56/drawings/pginty/simple/PictureComponent.java new file mode 100644 index 00000000..8dee0fb0 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/pginty/simple/PictureComponent.java @@ -0,0 +1,103 @@ +package edu.ucsb.cs56.drawings.pginty.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 Peter Ginty (fixed the snowmans's head) + @version for UCSB CS56, W16 +*/ + +// 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("Snowman with House - Peter Ginty", 20,20); + + } +} diff --git a/src/edu/ucsb/cs56/drawings/pginty/simple/PictureViewer.java b/src/edu/ucsb/cs56/drawings/pginty/simple/PictureViewer.java new file mode 100644 index 00000000..0bf87e6b --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/pginty/simple/PictureViewer.java @@ -0,0 +1,42 @@ +package edu.ucsb.cs56.drawings.pginty.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 Peter Ginty + * @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("Peter Ginty'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); + } +} diff --git a/src/edu/ucsb/cs56/drawings/tcisewski/SimpleGui1.java b/src/edu/ucsb/cs56/drawings/tcisewski/SimpleGui1.java new file mode 100644 index 00000000..16d01bdd --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/tcisewski/SimpleGui1.java @@ -0,0 +1,34 @@ +package edu.ucsb.cs56.drawings.tcisewski; + +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 T. Cisewski + @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 or else"); + + java.awt.Color myColor = new java.awt.Color(255,000,102); // 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/tcisewski/advanced/AllMyDrawings.java b/src/edu/ucsb/cs56/drawings/tcisewski/advanced/AllMyDrawings.java new file mode 100644 index 00000000..e2d36b91 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/tcisewski/advanced/AllMyDrawings.java @@ -0,0 +1,113 @@ +package edu.ucsb.cs56.drawings.tcisewski.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 Trenton Cisewski + * @version for UCSB CS56, W16 + */ + +public class AllMyDrawings +{ + /** Draw a picture with a few icecreams + */ + + public static void drawPicture1(Graphics2D g2) { + + IceCream i1 = new IceCream(100,250,50); + g2.setColor(Color.CYAN); g2.draw(i1); + + Shape i2 = ShapeTransforms.scaledCopyOfLL(i1,0.5,0.5); + i2 = ShapeTransforms.translatedCopyOf(i2,250,0); + g2.setColor(Color.BLACK); g2.draw(i2); + + i2 = ShapeTransforms.scaledCopyOfLL(i2,4,4); + i2 = ShapeTransforms.translatedCopyOf(i2,150,0); + + Stroke thick = new BasicStroke (4.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL); + + Stroke orig=g2.getStroke(); + g2.setStroke(thick); + g2.setColor(new Color(0x002FA7)); + g2.draw(i2); + + IceCreamWithSprinkles is1 = new IceCreamWithSprinkles(650,350,40); + IceCreamWithSprinkles is2 = new IceCreamWithSprinkles(200,350,50); + + g2.draw(is1); + g2.setColor(new Color(0x8F00FF)); g2.draw(is2); + + g2.setStroke(orig); + g2.setColor(Color.BLACK); + g2.drawString("A few ice cream cones by Trenton Cisewski", 20,20); + } + + + /** Draw a picture with a few icecreams with sprinkles + */ + public static void drawPicture2(Graphics2D g2) { + + g2.drawString("Some cones with and without sprinkles by Trenton Cisewski", 20,20); + + IceCream i1 = new IceCream(100,100,50); + Stroke thick = new BasicStroke (4.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL); + g2.setStroke(thick); + g2.setColor(new Color(0x002FA7)); + g2.draw(i1); + + IceCreamWithSprinkles is1 = new IceCreamWithSprinkles(250,100,50); + g2.setColor(new Color(0xE81B28)); + g2.draw(is1); + + Shape is2 = ShapeTransforms.rotatedCopyOf(is1, Math.PI); + is2 = ShapeTransforms.translatedCopyOf(is2,0,210); + g2.setColor(new Color(0x17BA21)); + g2.draw(is2); + + IceCreamWithSprinkles is3 = new IceCreamWithSprinkles(350,250,25); + g2.setColor(new Color(0xFF5733)); + g2.draw(is3); + + } + + /** Draw 4 icecreams all touching cones + */ + + public static void drawPicture3(Graphics2D g2) { + + // label the drawing + + g2.drawString("4 ice cream cones by Trenton Cisewski", 20,20); + + IceCream i1 = new IceCream(250,100,50); + Stroke thick = new BasicStroke (4.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL); + g2.setStroke(thick); + g2.setColor(new Color(0x002FA7)); + g2.draw(i1); + + Shape i2 = ShapeTransforms.rotatedCopyOf(i1, Math.PI); + i2 = ShapeTransforms.translatedCopyOf(i2,0,210); + g2.setColor(new Color(0xE81B28)); + g2.draw(i2); + + Shape i3 = ShapeTransforms.rotatedCopyOf(i1, Math.PI/2.0); + i3 = ShapeTransforms.translatedCopyOf(i3,110,110); + g2.setColor(new Color(0xFFFF00)); + g2.draw(i3); + + Shape i4 = ShapeTransforms.rotatedCopyOf(i1, Math.PI/-2.0); + i4 = ShapeTransforms.translatedCopyOf(i4,-110,110); + g2.setColor(new Color(0x17BA21)); + g2.draw(i4); + + } +} diff --git a/src/edu/ucsb/cs56/drawings/tcisewski/advanced/CoffeeCup.java b/src/edu/ucsb/cs56/drawings/tcisewski/advanced/CoffeeCup.java new file mode 100644 index 00000000..a5bf5333 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/tcisewski/advanced/CoffeeCup.java @@ -0,0 +1,85 @@ +package edu.ucsb.cs56.drawings.tcisewski.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/tcisewski/advanced/House.java b/src/edu/ucsb/cs56/drawings/tcisewski/advanced/House.java new file mode 100644 index 00000000..d5d76528 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/tcisewski/advanced/House.java @@ -0,0 +1,68 @@ +package edu.ucsb.cs56.drawings.tcisewski.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/tcisewski/advanced/HouseWithWindows.java b/src/edu/ucsb/cs56/drawings/tcisewski/advanced/HouseWithWindows.java new file mode 100644 index 00000000..51df4073 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/tcisewski/advanced/HouseWithWindows.java @@ -0,0 +1,55 @@ +package edu.ucsb.cs56.drawings.tcisewski.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/tcisewski/advanced/IceCream.java b/src/edu/ucsb/cs56/drawings/tcisewski/advanced/IceCream.java new file mode 100644 index 00000000..5bc91652 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/tcisewski/advanced/IceCream.java @@ -0,0 +1,50 @@ +package edu.ucsb.cs56.drawings.tcisewski.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; + +import edu.ucsb.cs56.drawings.tcisewski.simple.Circle; + +/** + * Created by trent on 10/28/2016. + */ +public class IceCream extends GeneralPathWrapper implements java.awt.Shape { + + /** + * Constructor for objects of class IceCream + * @param x x coordinate of center of ice cream + * @param y y coordinate of center of ice cream + * @param r radius of ice cream + */ + + public IceCream(double x, double y, double r) + { + + Circle cream = new Circle(x, y, r); + + double leftEdgeX = x-r; + double leftEdgeY = y; + double rightEdgeX = x+r; + double rightedgeY = y; + + Line2D.Double leftCone = + new Line2D.Double (leftEdgeX, y, + x, y + 3.5*r); + + Line2D.Double rightCone = + new Line2D.Double (rightEdgeX, y, + x, y + 3.5*r); + + GeneralPath iceCream = this.get(); + iceCream.append(cream, false); + iceCream.append(leftCone, false); + iceCream.append(rightCone, false); + + } +} diff --git a/src/edu/ucsb/cs56/drawings/tcisewski/advanced/IceCreamWithSprinkles.java b/src/edu/ucsb/cs56/drawings/tcisewski/advanced/IceCreamWithSprinkles.java new file mode 100644 index 00000000..2d2afd09 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/tcisewski/advanced/IceCreamWithSprinkles.java @@ -0,0 +1,72 @@ +package edu.ucsb.cs56.drawings.tcisewski.advanced; + +import java.awt.geom.GeneralPath; +import java.awt.geom.Line2D; + +/** + * Created by trent on 10/28/2016. + */ +public class IceCreamWithSprinkles extends IceCream { + + /** + * Constructor for objects of class IceCreamWithSprinkles + * @param x x coordinate of center of ice cream + * @param y y coordinate of center of ice cream + * @param r radius of ice cream + */ + + public IceCreamWithSprinkles(double x, double y, double r){ + + super(x, y, r); + + Line2D.Double sprink1 = + new Line2D.Double (x + (.5 * r), y + (.25 * r), + x + (.5 * r), y + (.5 * r)); + + Line2D.Double sprink2 = + new Line2D.Double (x - (.5 * r), y + (.75 * r), + x - (.5 * r), y + (.33 * r)); + + + Line2D.Double sprink3 = + new Line2D.Double (x + (.75 * r), y + (.5 * r), + x + (.25 * r), y + (.5 * r)); + + Line2D.Double sprink4 = + new Line2D.Double (x - (.33 * r), y - (.5 * r), + x - (.75 * r), y - (.5 * r)); + + Line2D.Double sprink5 = + new Line2D.Double (x + (.75 * r), y, + x + (.75 * r), y + (.25 * r)); + + Line2D.Double sprink6 = + new Line2D.Double (x - (.75 * r), y, + x - (.75 * r), y + (.25 * r)); + + + Line2D.Double sprink7 = + new Line2D.Double (x, y + (.75 * r), + x + (.25 * r), y + (.75 * r)); + + Line2D.Double sprink8 = + new Line2D.Double (x, y - (.75 * r), + x + (.25 * r), y - (.75 * r)); + + Line2D.Double sprink9 = + new Line2D.Double (x + (.25 * r), y, + x - (.25 * r), y); + + GeneralPath creamWithSprinkles = this.get(); + creamWithSprinkles.append(sprink1, false); + creamWithSprinkles.append(sprink2, false); + creamWithSprinkles.append(sprink3, false); + creamWithSprinkles.append(sprink4, false); + creamWithSprinkles.append(sprink5, false); + creamWithSprinkles.append(sprink6, false); + creamWithSprinkles.append(sprink7, false); + creamWithSprinkles.append(sprink8, false); + creamWithSprinkles.append(sprink9, false); + + } +} diff --git a/src/edu/ucsb/cs56/drawings/tcisewski/advanced/MultiPictureComponent.java b/src/edu/ucsb/cs56/drawings/tcisewski/advanced/MultiPictureComponent.java new file mode 100644 index 00000000..ddba1185 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/tcisewski/advanced/MultiPictureComponent.java @@ -0,0 +1,49 @@ +package edu.ucsb.cs56.drawings.tcisewski.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/tcisewski/advanced/MultiPictureViewer.java b/src/edu/ucsb/cs56/drawings/tcisewski/advanced/MultiPictureViewer.java new file mode 100644 index 00000000..848af397 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/tcisewski/advanced/MultiPictureViewer.java @@ -0,0 +1,52 @@ +package edu.ucsb.cs56.drawings.tcisewski.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(640,480); // @@@ MODIFY THIS LINE IF YOU LIKE + + // Set your own title + frame.setTitle("Phill'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/tcisewski/advanced/WritePictureToFile.java b/src/edu/ucsb/cs56/drawings/tcisewski/advanced/WritePictureToFile.java new file mode 100644 index 00000000..2ea58923 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/tcisewski/advanced/WritePictureToFile.java @@ -0,0 +1,83 @@ +package edu.ucsb.cs56.drawings.tcisewski.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/tcisewski/simple/Circle.java b/src/edu/ucsb/cs56/drawings/tcisewski/simple/Circle.java new file mode 100644 index 00000000..c1f5a5d9 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/tcisewski/simple/Circle.java @@ -0,0 +1,31 @@ +package edu.ucsb.cs56.drawings.tcisewski.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/tcisewski/simple/PictureComponent.java b/src/edu/ucsb/cs56/drawings/tcisewski/simple/PictureComponent.java new file mode 100644 index 00000000..f97a3bad --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/tcisewski/simple/PictureComponent.java @@ -0,0 +1,109 @@ +package edu.ucsb.cs56.drawings.tcisewski.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 Trenton Cisewski (fixed the snowmans's head) + @version for UCSB CS56, W16 +*/ + +// 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 * 3.5 - topRadius, + topRadius + ); + g2.draw(snowManTopCircle); + + + // @@@ FINALLY, SIGN AND LABEL YOUR DRAWING + // @@@ 20, 20 are suggested coordinates, but you may change them + + g2.drawString("A snowman with 3 levels. Trenton Cisewski", 20,20); + + } +} diff --git a/src/edu/ucsb/cs56/drawings/tcisewski/simple/PictureViewer.java b/src/edu/ucsb/cs56/drawings/tcisewski/simple/PictureViewer.java new file mode 100644 index 00000000..a096c1c9 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/tcisewski/simple/PictureViewer.java @@ -0,0 +1,42 @@ +package edu.ucsb.cs56.drawings.tcisewski.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); + } +} diff --git a/src/edu/ucsb/cs56/drawings/trevorhecht/SimpleGui1.java b/src/edu/ucsb/cs56/drawings/trevorhecht/SimpleGui1.java new file mode 100644 index 00000000..fde8ea72 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/trevorhecht/SimpleGui1.java @@ -0,0 +1,34 @@ +package edu.ucsb.cs56.drawings.trevorhecht; + +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!!!!") ; + + java.awt.Color myColor = new java.awt.Color(204,000,255); // 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/trevorhecht/advanced/AllMyDrawings.java b/src/edu/ucsb/cs56/drawings/trevorhecht/advanced/AllMyDrawings.java new file mode 100755 index 00000000..76990a6f --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/trevorhecht/advanced/AllMyDrawings.java @@ -0,0 +1,113 @@ +package edu.ucsb.cs56.drawings.trevorhecht.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 houses + */ + + public static void drawPicture1(Graphics2D g2) { + + Note h1 = new Note(100,250,50); + g2.setColor(Color.CYAN); g2.draw(h1); + + // Make a black house 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 house 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 houses with Windows + + // HouseWithWindows hw1 = new HouseWithWindows(50,350,40,75); + // HouseWithWindows hw2 = new HouseWithWindows(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 houses by Phill Conrad", 20,20); + } + + + /** Draw a picture with a few houses and coffee cups + */ + public static void drawPicture2(Graphics2D g2) { + EighthNote h1 = new EighthNote(100,250,50); + g2.setColor(Color.CYAN); g2.draw(h1); + + Shape h2 = ShapeTransforms.scaledCopyOfLL(h1,0.5,0.5); + h2 = ShapeTransforms.translatedCopyOf(h2,150,0); + + + + Stroke thick = new BasicStroke (4.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL); + + Stroke orig=g2.getStroke(); + g2.setStroke(thick); + g2.setColor(new Color(0x002FA7)); + + g2.setStroke(orig); + g2.setColor(Color.BLACK); + + + } + + /** Draw a different picture with a few houses and coffee cups + */ + + public static void drawPicture3(Graphics2D g2) { + + // label the drawing + + g2.drawString("A bunch of Coffee Cups by Phill Conrad", 20,20); + + + // Draw some coffee cups. + + CoffeeCup large = new CoffeeCup(100,50,225,150); + CoffeeCup smallCC = new CoffeeCup(20,50,40,30); + + g2.setColor(Color.RED); g2.draw(large); + g2.setColor(Color.GREEN); g2.draw(smallCC); + +} + + +} diff --git a/src/edu/ucsb/cs56/drawings/trevorhecht/advanced/Circle.java b/src/edu/ucsb/cs56/drawings/trevorhecht/advanced/Circle.java new file mode 100644 index 00000000..2f2927e9 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/trevorhecht/advanced/Circle.java @@ -0,0 +1,31 @@ +package edu.ucsb.cs56.drawings.trevorhecht.advanced; + +/** + * 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/trevorhecht/advanced/CoffeeCup.java b/src/edu/ucsb/cs56/drawings/trevorhecht/advanced/CoffeeCup.java new file mode 100755 index 00000000..8a912fdb --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/trevorhecht/advanced/CoffeeCup.java @@ -0,0 +1,85 @@ +package edu.ucsb.cs56.drawings.trevorhecht.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/trevorhecht/advanced/EighthNote.java b/src/edu/ucsb/cs56/drawings/trevorhecht/advanced/EighthNote.java new file mode 100644 index 00000000..4960ab95 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/trevorhecht/advanced/EighthNote.java @@ -0,0 +1,66 @@ +package edu.ucsb.cs56.drawings.trevorhecht.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 EighthNote extends Note implements Shape +{ + + public EighthNote(double x, double y, double radius) //house + { + super(x,y,radius); + + double circleradius = radius; + double lineheight = radius * 4.5; + double linewidth = radius * .42; + double Circle_x = x; + double line_x = x + radius; + double Circle_y = y; + double line_y = y - 4.5*radius; + + + + Circle secondcircleOfNote = new Circle + ( + Circle_x + lineheight * .7, + Circle_y, + circleradius + ); + + Rectangle2D.Double secondLine = + new Rectangle2D.Double(line_x + linewidth, .12* lineheight , + lineheight * .7 - linewidth, linewidth); + + Rectangle2D.Double thirdLine = + new Rectangle2D.Double(line_x + lineheight * .7, line_y, + linewidth, lineheight); + + + + + GeneralPath note = this.get(); + note.append(secondcircleOfNote, false); + note.append(secondLine, false); + note.append(thirdLine, false); + + + + + } + +} + diff --git a/src/edu/ucsb/cs56/drawings/trevorhecht/advanced/House.java b/src/edu/ucsb/cs56/drawings/trevorhecht/advanced/House.java new file mode 100755 index 00000000..586e19d4 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/trevorhecht/advanced/House.java @@ -0,0 +1,68 @@ +package edu.ucsb.cs56.drawings.trevorhecht.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/trevorhecht/advanced/HouseWithWindows.java b/src/edu/ucsb/cs56/drawings/trevorhecht/advanced/HouseWithWindows.java new file mode 100755 index 00000000..3485382b --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/trevorhecht/advanced/HouseWithWindows.java @@ -0,0 +1,55 @@ +package edu.ucsb.cs56.drawings.trevorhecht.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/trevorhecht/advanced/MultiPictureComponent.java b/src/edu/ucsb/cs56/drawings/trevorhecht/advanced/MultiPictureComponent.java new file mode 100644 index 00000000..fcb12e72 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/trevorhecht/advanced/MultiPictureComponent.java @@ -0,0 +1,49 @@ +package edu.ucsb.cs56.drawings.trevorhecht.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/trevorhecht/advanced/MultiPictureViewer.java b/src/edu/ucsb/cs56/drawings/trevorhecht/advanced/MultiPictureViewer.java new file mode 100644 index 00000000..8431abdc --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/trevorhecht/advanced/MultiPictureViewer.java @@ -0,0 +1,52 @@ +package edu.ucsb.cs56.drawings.trevorhecht.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(640,480); // @@@ MODIFY THIS LINE IF YOU LIKE + + // Set your own title + frame.setTitle("Trevor Hecht's Note 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/trevorhecht/advanced/Note.java b/src/edu/ucsb/cs56/drawings/trevorhecht/advanced/Note.java new file mode 100644 index 00000000..4b82e227 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/trevorhecht/advanced/Note.java @@ -0,0 +1,59 @@ +package edu.ucsb.cs56.drawings.trevorhecht.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 Note 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 Note(double x, double y, double radius) + { + + double circleradius = radius; + double lineheight = radius * 4.5; + double linewidth = radius * .42; + double Circle_x = x; + double line_x = x + radius; + double Circle_y = y; + double line_y = y - 4.5*radius; + + + // Make the first story + Circle bottomOfNote = + new Circle + ( + Circle_x, + Circle_y, + circleradius + ); + + Rectangle2D.Double firstLine = + new Rectangle2D.Double(line_x, line_y , + linewidth, lineheight); + GeneralPath note = this.get(); + note.append(bottomOfNote, false); + note.append(firstLine, false); + + } +} diff --git a/src/edu/ucsb/cs56/drawings/trevorhecht/advanced/WritePictureToFile.java b/src/edu/ucsb/cs56/drawings/trevorhecht/advanced/WritePictureToFile.java new file mode 100755 index 00000000..d5cf7188 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/trevorhecht/advanced/WritePictureToFile.java @@ -0,0 +1,83 @@ +package edu.ucsb.cs56.drawings.trevorhecht.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/trevorhecht/simple/Circle.java b/src/edu/ucsb/cs56/drawings/trevorhecht/simple/Circle.java new file mode 100644 index 00000000..78a30ad8 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/trevorhecht/simple/Circle.java @@ -0,0 +1,31 @@ +package edu.ucsb.cs56.drawings.trevorhecht.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/trevorhecht/simple/PictureComponent.java b/src/edu/ucsb/cs56/drawings/trevorhecht/simple/PictureComponent.java new file mode 100644 index 00000000..f556aa00 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/trevorhecht/simple/PictureComponent.java @@ -0,0 +1,110 @@ +package edu.ucsb.cs56.drawings.trevorhecht.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 @@@ ADD YOUR NAME (fixed the snowmans's head) + @version for UCSB CS56, W16 +*/ + +// 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); + + Circle snowManTopCircle = + new Circle + ( + snowManCenterBottomX, + snowManCenterBottomY - bottomRadius * 2 - middleRadius*2 - + topRadius, topRadius + ); + g2.draw(snowManTopCircle); + + // @@@ ADD CODE HERE TO DRAW THE TOP CIRCLE + + + + // @@@ FINALLY, SIGN AND LABEL YOUR DRAWING + // @@@ 20, 20 are suggested coordinates, but you may change them + + g2.drawString("Trevor Hecht", 20,20); + + } +} diff --git a/src/edu/ucsb/cs56/drawings/trevorhecht/simple/PictureViewer.java b/src/edu/ucsb/cs56/drawings/trevorhecht/simple/PictureViewer.java new file mode 100644 index 00000000..f46d8e99 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/trevorhecht/simple/PictureViewer.java @@ -0,0 +1,42 @@ +package edu.ucsb.cs56.drawings.trevorhecht.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); + } +} diff --git a/src/edu/ucsb/cs56/drawings/wpeery/SimpleGui1.java b/src/edu/ucsb/cs56/drawings/wpeery/SimpleGui1.java new file mode 100644 index 00000000..9ff34bec --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/wpeery/SimpleGui1.java @@ -0,0 +1,34 @@ +package edu.ucsb.cs56.drawings.wpeery; + +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: Wesley Peery + @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("DONT click me") ; + + java.awt.Color myColor = new java.awt.Color(100,200,005); // 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/wpeery/advanced/AllMyDrawings.java b/src/edu/ucsb/cs56/drawings/wpeery/advanced/AllMyDrawings.java new file mode 100755 index 00000000..ba15cba5 --- /dev/null +++ b/src/edu/ucsb/cs56/drawings/wpeery/advanced/AllMyDrawings.java @@ -0,0 +1,147 @@ +package edu.ucsb.cs56.drawings.wpeery.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 Wesley Peery + * @version for UCSB CS56, F16 + */ + +public class AllMyDrawings +{ + /** Draw a picture with a few balls and bowling balls + */ + + public static void drawPicture1(Graphics2D g2) { + + BowlingBall b1 = new BowlingBall(100,250,50); + g2.setColor(Color.CYAN); g2.draw(b1); + + // Make a black ball that's half the size, + // and moved over 150 pixels in x direction + + Shape b2 = ShapeTransforms.scaledCopyOfLL(b1,0.5,0.5); + b2 = ShapeTransforms.translatedCopyOf(b2,150,0); + g2.setColor(Color.BLACK); g2.draw(b2); + + // Here's a ball that's 4x as big (2x the original) + // and moved over 150 more pixels to right. + b2 = ShapeTransforms.scaledCopyOfLL(b2,4,4); + b2 = ShapeTransforms.translatedCopyOf(b2,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(b2); + + // Draw two houses with Windows + + Ball ball1 = new Ball(50,350,40); + Ball ball2 = new Ball(200,350,100); + + g2.draw(ball1); + g2.setColor(new Color(0x8F00FF)); g2.draw(ball2); + + // @@@ FINALLY, SIGN AND LABEL YOUR DRAWING + + g2.setStroke(orig); + g2.setColor(Color.BLACK); + g2.drawString("A few balls and bowling balls by Wesley Peery", 20,20); + } + + + /** Draw a picture of a bowling ball with bowling balls for finger holes + */ + public static void drawPicture2(Graphics2D g2) { + + // A bowling ball made from bowling balls + double x = 325;//only need to initialize these values + double y = 225; + double r = 200; + + g2.setColor(new Color(0x8F00FF)); + Ball ball = new Ball(x,y,r); + g2.draw(ball);//draws the shell + BowlingBall b1 = new BowlingBall(x,y,r/8); + // put b2 and b3 in the correct positions + Shape b2 = ShapeTransforms.translatedCopyOf(b1,r/5,-r/2); + Shape b3 = ShapeTransforms.translatedCopyOf(b1,-r/5,-r/2); + // Rotate the b3 and b2 + b3 = ShapeTransforms.rotatedCopyOf(b3, Math.PI/4.0); + b2 = ShapeTransforms.rotatedCopyOf(b2, Math.PI/2.0); + // draw the bowling balls + g2.draw(b3); + g2.draw(b2); + g2.draw(b1); + + // @@@ FINALLY, SIGN AND LABEL YOUR DRAWING + Stroke orig=g2.getStroke(); + g2.setStroke(orig); + g2.setColor(Color.BLACK); + g2.drawString("Inception by Wesley Peery", 20,20); + } + + /** Draw a picture of a bowling ball in motion with arrows to signify motion + */ + + public static void drawPicture3(Graphics2D g2) { + // A bowling ball in motion, with arrows + Stroke orig=g2.getStroke(); + Stroke thick = new BasicStroke (4.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL); + g2.setStroke(thick); + + double x = 150; // initial values (you only need to adjust these values to adjust the drawing) + double y = 200; + double r = 50; + int numBalls = 6;// end initial values + + g2.setColor(new Color(0x3355FF)); + BowlingBall ball = new BowlingBall(x,y,r); + g2.draw(ball); + double degree = 0; + + //draw bowling balls + for(int i=1; i