Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Modify the NervousShapes program so that it displays equilateral triangles as we

ID: 3758414 • Letter: M

Question

Modify the NervousShapes program so that it displays equilateral triangles as well as circles and rectangles. You will need to define a Triangle class containing a single instance variable, representing the length of one of the triangle’s sides. Have the program create circles, rectangles, and triangles with equal probability.

The DrawingPanel class provides a simple interface for drawing persistent
images using a Graphics object. An internal BufferedImage object is used
to keep track of what has been drawn. A client of the class simply
constructs a DrawingPanel of a particular size and then draws on it with
the Graphics object, setting the background color if they so choose.

To ensure that the image is always displayed, a timer calls repaint at
regular intervals.
*/
package NervousShapes;

import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.imageio.*;
import javax.swing.*;
import javax.swing.event.*;

public class DrawingPanel implements ActionListener {
    public static final int DELAY = 50; // delay between repaints in millis

    private static final String DUMP_IMAGE_PROPERTY_NAME = "drawingpanel.save";
    private static String TARGET_IMAGE_FILE_NAME = null;
    private static final boolean PRETTY = true; // true to anti-alias
    private static boolean DUMP_IMAGE = true; // true to write DrawingPanel to file

    private int width, height;    // dimensions of window frame
    private JFrame frame;         // overall window frame
    private JPanel panel;         // overall drawing surface
    private BufferedImage image; // remembers drawing commands
    private Graphics2D g2;        // graphics context for painting
    private JLabel statusBar;     // status bar showing mouse position
    private long createTime;

    static {
        TARGET_IMAGE_FILE_NAME = System.getProperty(DUMP_IMAGE_PROPERTY_NAME);
        DUMP_IMAGE = (TARGET_IMAGE_FILE_NAME != null);
    }

    // construct a drawing panel of given width and height enclosed in a window
    public DrawingPanel(int width, int height) {
        this.width = width;
        this.height = height;
        this.image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);

        this.statusBar = new JLabel(" ");
        this.statusBar.setBorder(BorderFactory.createLineBorder(Color.BLACK));

        this.panel = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 0));
        this.panel.setBackground(Color.WHITE);
        this.panel.setPreferredSize(new Dimension(width, height));
        this.panel.add(new JLabel(new ImageIcon(image)));

        // listen to mouse movement
        MouseInputAdapter listener = new MouseInputAdapter() {
            public void mouseMoved(MouseEvent e) {
                DrawingPanel.this.statusBar.setText("(" + e.getX() + ", " + e.getY() + ")");
            }

            public void mouseExited(MouseEvent e) {
                DrawingPanel.this.statusBar.setText(" ");
            }
        };
        this.panel.addMouseListener(listener);
        this.panel.addMouseMotionListener(listener);

        this.g2 = (Graphics2D)image.getGraphics();
        this.g2.setColor(Color.BLACK);
        if (PRETTY) {
            this.g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            this.g2.setStroke(new BasicStroke(1.1f));
        }

        this.frame = new JFrame("Building Java Programs - Drawing Panel");
        this.frame.setResizable(false);
        this.frame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                if (DUMP_IMAGE) {
                    DrawingPanel.this.save(TARGET_IMAGE_FILE_NAME);
                }
                System.exit(0);
            }
        });
        this.frame.getContentPane().add(panel);
        this.frame.getContentPane().add(statusBar, "South");
        this.frame.pack();
        this.frame.setVisible(true);
        if (DUMP_IMAGE) {
            createTime = System.currentTimeMillis();
            this.frame.toBack();
        } else {
            this.toFront();
        }

        // repaint timer so that the screen will update
        new Timer(DELAY, this).start();
    }

    // used for an internal timer that keeps repainting
    public void actionPerformed(ActionEvent e) {
        this.panel.repaint();
        if (DUMP_IMAGE && System.currentTimeMillis() > createTime + 4 * DELAY) {
            this.frame.setVisible(false);
            this.frame.dispose();
            this.save(TARGET_IMAGE_FILE_NAME);
            System.exit(0);
        }
    }

    // obtain the Graphics object to draw on the panel
    public Graphics2D getGraphics() {
        return this.g2;
    }

    // set the background color of the drawing panel
    public void setBackground(Color c) {
        this.panel.setBackground(c);
    }

-----------------------------------------------------------------------------------

// Displays a frame containing a random mixture of circles
// and rectangles with random colors, sizes, and positions.
// The shapes periodically change position, with the
// direction of motion chosen randomly for each shape. The
// new x coordinate for each shape will either be the same
// as the old x coordinate, one pixel smaller, or one pixel
// larger; the new y coordinate will be computed in a
// similar manner. Shapes will be constrained so that they
// do not move outside the drawing area.
package NervousShapes;

import java.awt.*;

public class NervousShapes {
// Constants
private static final int DELAY = 100;
    // Animation delay (milliseconds)
private static final int MAX_SIZE = 40;
    // Maximum width and height of a shape
private static final int MIN_SIZE = 10;
    // Minimum width and height of a shape
private static final int NUM_SHAPES = 90;
    // Number of shapes
private static final int WINDOW_SIZE = 400;
    // Width and height of drawable portion of frame

private static final int CHANGE_RANGE = 2;
// how far the new position can be from the previous position

private static DrawingPanel panel;
private static Graphics g;
    // Graphics context for frame
private static Shape shapes[] = new Shape[NUM_SHAPES];
    // Array of shapes

public static void main(String[] args) {
    createWindow();
    createShapes();
    animateShapes();
}

///////////////////////////////////////////////////////////
// NAME:       createWindow
// BEHAVIOR:   Creates a frame labeled "Nervous Shapes",
//             displays the frame, and sets the size of
//             the frame (using the WINDOW_SIZE class
//             variable). Assigns the frame to the df
//             class variable, and assigns the frame's
//             graphics context to the g class variable.
// PARAMETERS: None
// RETURNS:    Nothing
///////////////////////////////////////////////////////////
private static void createWindow() {
    // Create the drawing panel
   panel = new DrawingPanel(WINDOW_SIZE, WINDOW_SIZE);

    // Get the graphics context
    g = panel.getGraphics();
}

///////////////////////////////////////////////////////////
// NAME:       createShapes
// BEHAVIOR:   Creates enough Circle and Rectangle objects
//             to fill the shapes array. Each shape has a
//             random color, size, and position. The height
//             and width of each shape must lie between
//             MIN_SIZE and MAX_SIZE (inclusive). The
//             position is chosen so that the shape is
//             completely within the drawing area.
// PARAMETERS: None
// RETURNS:    Nothing
///////////////////////////////////////////////////////////
private static void createShapes() {
    for (int i = 0; i < shapes.length; i++) {
      // Select a random color
      int red = generateRandomInt(0, 255);
      int green = generateRandomInt(0, 255);
      int blue = generateRandomInt(0, 255);
      Color color = new Color(red, green, blue);
      // Decide whether to create a circle or a rectangle
      if (Math.random() < 0.5) {
        // Generate a circle with a random size and position
        int diameter = generateRandomInt(MIN_SIZE, MAX_SIZE);
        int x = generateRandomInt(0, WINDOW_SIZE - diameter);
        int y = generateRandomInt(0, WINDOW_SIZE - diameter);
        shapes[i] = new Circle(x, y, color, diameter);
      } else {
        // Generate a rectangle with a random size and
        // position
        int width = generateRandomInt(MIN_SIZE, MAX_SIZE);
        int height = generateRandomInt(MIN_SIZE, MAX_SIZE);
        int x = generateRandomInt(0, WINDOW_SIZE - width);
        int y = generateRandomInt(0, WINDOW_SIZE - height);
        shapes[i] = new Rectangle(x, y, color, width, height);
      }
    }
}

///////////////////////////////////////////////////////////
// NAME:       animateShapes
// BEHAVIOR:   Establishes an infinite loop in which the
//             shapes are animated. During each loop
//             iteration, the drawing area is cleared and
//             the shapes are then drawn at new positions.
//             The new x and y coordinates for each shape
//             will either be the same as the old ones,
//             one pixel smaller, or one pixel larger. A
//             shape is not moved if doing so would cause
//             any portion of the shape to go outside the
//             drawing area. At the end of each animation
//             cycle, there is a brief pause, which is
//             controlled by the delay constant.
// PARAMETERS: None
// RETURNS:    Nothing
///////////////////////////////////////////////////////////
private static void animateShapes() {
    while (true) {
      // Clear drawing area
      g.setColor(Color.white);
      g.fillRect(0, 0, WINDOW_SIZE - 1, WINDOW_SIZE - 1);
      for (int i = 0; i < shapes.length; i++) {
        // Change the x coordinate for shape i
        int dx = generateRandomInt(-CHANGE_RANGE, +CHANGE_RANGE);
        int newX = shapes[i].getX() + dx;
        if (newX >= 0 &&
            newX + shapes[i].getWidth() < WINDOW_SIZE)
          shapes[i].move(dx, 0);

        // Change the y coordinate for shape i
        int dy = generateRandomInt(-CHANGE_RANGE, +CHANGE_RANGE);
        int newY = shapes[i].getY() + dy;
        if (newY >= 0 &&
            newY + shapes[i].getHeight() < WINDOW_SIZE)
          shapes[i].move(0, dy);

        // Draw shape i at its new position
        shapes[i].draw(g);
      }
    
      panel.sleep(DELAY);

    }
}

///////////////////////////////////////////////////////////
// NAME:       generateRandomInt
// BEHAVIOR:   Generates a random integer within a
//             specified range.
// PARAMETERS: min - the lower bound of the range
//             max - the upper bound of the range
// RETURNS:    A random integer that is greater than or
//             equal to min and less than or equal to max
///////////////////////////////////////////////////////////
private static int generateRandomInt(int min, int max) {
    return (int) ((max - min + 1) * Math.random()) + min;
}
}
---------------------------------------------------------------------------

package NervousShapes;

import java.awt.*;

public class Rectangle extends Shape {
// Instance variables
private int width;
private int height;

// Constructor
public Rectangle(int x, int y, Color color,
                   int width, int height) {
    super(x, y, color);
    this.width = width;
    this.height = height;
}
// Instance methods
public void draw(Graphics g) {
    g.setColor(getColor());
    g.fillRect(getX(), getY(), width, height);
}

public int getHeight() {
    return height;
}

public int getWidth() {
    return width;
}
}
----------------------------------------------------------------------

package NervousShapes;

import java.awt.*;

public abstract class Shape {
// Instance variables
private int x;
private int y;
private Color color;

// Constructor
protected Shape(int x, int y, Color color) {
    this.x = x;
    this.y = y;
    this.color = color;
}
// Abstract methods
public abstract void draw(Graphics g);
public abstract int getHeight();
public abstract int getWidth();

// Other instance methods
public Color getColor() {
    return color;
}

public int getX() {
    return x;
}

public int getY() {
    return y;
}
public void move(int dx, int dy) {
    x += dx;
    y += dy;
}

public void setColor(Color color) {
    this.color = color;
}
}
---------------------------------------------------------------------------

package NervousShapes;

import java.awt.*;

public class Circle extends Shape {
// Instance variables
private int diameter;

// Constructor
public Circle(int x, int y, Color color, int diameter) {
    super(x, y, color);
    this.diameter = diameter;
}
// Instance methods
public void draw(Graphics g) {
    g.setColor(getColor());
    g.fillOval(getX(), getY(), diameter, diameter);
}

public int getHeight() {
    return diameter;
}

public int getWidth() {
    return diameter;
}
}

Explanation / Answer

import java.awt.*;

public class NervousShapes

{

    private static final int DELAY = 10;

    private static final int MAX_SIZE = 50;

    private static final int MIN_SIZE = 10;

    private static final int NUM_SHAPES = 100;

    private static final int WINDOW_SIZE = 500;

    private static DrawableFrame df;

    private static Graphics g;

    private static Shape shapes[] = new Shape[NUM_SHAPES];

    private static void createWindow ()

    {

        df = new DrawableFrame ("Nervous Shapes");

        df.setVisible (true);

        //df.show(); changed by ERB

        df.setSize (WINDOW_SIZE, WINDOW_SIZE);

        g = df.getGraphicsContext ();

    }

    private static void createShapes ()

    {

        for (int i = 0; i < shapes.length; i++)

        {

            int red = generateRandomInt (0, 255);

            int green = generateRandomInt (0, 255);

            int blue = generateRandomInt (0, 255);

            double randomValue;

            Color color = new Color (red, green, blue);

            randomValue = Math.random ();

            if (randomValue < 0.5)

            {

                int diameter = generateRandomInt (MIN_SIZE, MAX_SIZE);

                int x = generateRandomInt (0, WINDOW_SIZE - diameter);

                int y = generateRandomInt (0, WINDOW_SIZE - diameter);

                shapes[i] = new Circle (x, y, color, diameter);

            }

            else if (randomValue > 0.5)

            {

                int width = generateRandomInt (MIN_SIZE, MAX_SIZE);

                int height = generateRandomInt (MIN_SIZE, MAX_SIZE);

                int x = generateRandomInt (0, WINDOW_SIZE - width);

                int y = generateRandomInt (0, WINDOW_SIZE - height);

                shapes[i] = new Rectangle (x, y, color, width, height);

            }

            [color="#FF0000"]

         else

            {

                int sideLength = generateRandomInt (MIN_SIZE, MAX_SIZE);

                int x = generateRandomInt (0, WINDOW_SIZE - sideLength);

                int y = generateRandomInt (0, WINDOW_SIZE - sideLength);

                shapes[i] = new Triangle (x, y, color, sideLength);

            }[/color]

        }

    }

    private static void animateShapes ()

    {

        while (true)

        {

            g.setColor (Color.white);

            g.fillRect (0, 0, WINDOW_SIZE - 1, WINDOW_SIZE - 1);

            for (int i = 0; i < shapes.length; i++)

            {

                int dx = generateRandomInt (-1, +1);

                int newX = shapes[i].getX () + dx;

                if (newX >= 0 && newX + shapes[i].getWidth () < WINDOW_SIZE)

                    shapes[i].move (dx, 0);

                int dy = generateRandomInt (-1, +1);

                int newY = shapes[i].getY () + dy;

                if (newY >= 0 && newY + shapes[i].getHeight () < WINDOW_SIZE)

                    shapes[i].move (0, dy);

                shapes[i].draw (g);

            }

            df.repaint ();

            // Pause briefly

            try

            {

                Thread.sleep (DELAY);

            }

            catch (InterruptedException e)

            {}

        }

    }

    private static int generateRandomInt (int min, int max)

    {

        return (int) ((max - min + 1) * Math.random ()) + min;

    }

    public static void main (String[] args)

    {

        createWindow ();

        createShapes ();

        animateShapes ();

    }

}

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote