import java.awt.*; import java.awt.geom.*; /** * A circle that can be manipulated and that draws itself on a canvas. * This version includes some methods that highlight object references. * The copy constructor takes another Circle as input, for example, * and returnSmaller returns the smaller of two Circle objects. * * @author Michael Kölling and David J. Barnes and Brad Richards * @version 2016.02.29 */ public class Circle { private int diameter; private int xPosition; private int yPosition; private String color; private boolean isVisible; private final int MAX_SIZE = 300; // This defines a constant /** * Create a new circle at default position with default color. */ public Circle() { diameter = 68; xPosition = 20; yPosition = 60; color = "blue"; isVisible = false; } /** * This is a copy constructor. It takes a reference to another * circle, and sets "us" up to look just like them. We're allowed * to peek inside otherCircle's private fields because we're a * Circle and they're a Circle. */ public Circle(Circle otherCircle) { diameter = otherCircle.diameter; xPosition = otherCircle.xPosition; yPosition = otherCircle.yPosition; color = otherCircle.color; if (otherCircle.isVisible) { makeVisible(); // Draw us, set isVisible to true } else { isVisible = false; // We're not visible either } } /** * An equals method for circles. We'll decide circles are "equal" if * they're the same diameter and color. (I'm comparing "myself" to * the circle "other".) */ public boolean equals(Circle other) { if (diameter == other.diameter && color.equals(other.color)) { return true; } else { return false; } } /** * Compare this circle to the one passed in, and return an object * reference to the smaller of the two. */ public Circle returnSmaller(Circle other) { if (diameter < other.diameter) { return this; // I win } else { return other; // they win } } /** * This method takes references to two circles and creates and * returns a brand new circle whose size and position are the * averages of the two inputs. If either of the input circles * are visible, the new circle is made visible as well. * * @param c1 A reference to a circle object. * @param c2 A reference to another circle object. * @return A new circle whose size and position is the average * of c1's and c2's. */ public Circle makeAverageCircle(Circle c1, Circle c2) { Circle newCircle = new Circle(); // Make a new circle newCircle.diameter = (c1.diameter + c2.diameter) / 2; newCircle.xPosition = (c1.xPosition + c2.xPosition) / 2; newCircle.yPosition = (c1.yPosition + c2.yPosition) / 2; if (c1.isVisible || c2.isVisible) { newCircle.makeVisible(); } else { newCircle.isVisible = false; } return newCircle; // Share our new circle with the caller } // --- Original methods from here down /** * Make this circle visible. If it was already visible, do nothing. */ public void makeVisible() { isVisible = true; draw(); } /** * Make this circle invisible. If it was already invisible, do nothing. */ public void makeInvisible() { erase(); isVisible = false; } /** * Move the circle a few pixels to the right. */ public void moveRight() { moveHorizontal(20); } /** * Move the circle a few pixels to the left. */ public void moveLeft() { moveHorizontal(-20); } /** * Move the circle a few pixels up. */ public void moveUp() { moveVertical(-20); } /** * Move the circle a few pixels down. */ public void moveDown() { moveVertical(20); } /** * Move the circle horizontally by 'distance' pixels. */ public void moveHorizontal(int distance) { erase(); xPosition += distance; draw(); } /** * Move the circle vertically by 'distance' pixels. */ public void moveVertical(int distance) { erase(); yPosition += distance; draw(); } /** * Slowly move the circle horizontally by 'distance' pixels. */ public void slowMoveHorizontal(int distance) { int delta; if(distance < 0) { delta = -1; distance = -distance; } else { delta = 1; } for(int i = 0; i < distance; i++) { xPosition += delta; draw(); } } /** * Slowly move the circle vertically by 'distance' pixels. */ public void slowMoveVertical(int distance) { int delta; if(distance < 0) { delta = -1; distance = -distance; } else { delta = 1; } for(int i = 0; i < distance; i++) { yPosition += delta; draw(); } } /** * Change the size to the new size (in pixels). Size must be >= 0. */ public void changeSize(int newDiameter) { erase(); if (newDiameter <= MAX_SIZE) { diameter = newDiameter; } else { // Complain about it System.out.println("I ignored you. " + newDiameter+" is too large"); } draw(); } /** * Change the color. Valid colors are "red", "yellow", "blue", "green", * "magenta" and "black". */ public void changeColor(String newColor) { color = newColor; draw(); } /** * Draw the circle with current specifications on screen. */ private void draw() { if(isVisible) { Canvas canvas = Canvas.getCanvas(); canvas.draw(this, color, new Ellipse2D.Double(xPosition, yPosition, diameter, diameter)); canvas.wait(10); } } /** * Erase the circle on screen. */ private void erase() { if(isVisible) { Canvas canvas = Canvas.getCanvas(); canvas.erase(this); } } }