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

Modify the MyLine , MyOval and MyRectangle classes of Exercise 8.1 and Exercise

ID: 3625899 • Letter: M

Question

Modify the MyLine , MyOval and MyRectangle classes of Exercise 8.1 and Exercise 9.1 to create the class hierarchy in Fig. 10.17. Classes of theMyShape hierarchy should be "smart" shape classes that know how to draw themselves (if provided with a Graphics object that tells them where to draw). Once the program creates an object from this hierarchy, it can manipulate it polymorphically for the rest of its lifetime as a MyShape .

Figure 10.17. MyShape hierarchy.

(This item is displayed on page 497 in the print version)

In your solution, class MyShape in Fig. 10.17 must be abstract . Since MyShape represents any shape in general, you cannot implement a drawmethod without knowing exactly what shape it is. The data representing the coordinates and color of the shapes in the hierarchy should be declared asprivate members of class MyShape . In addition to the common data, class MyShape should declare the following methods :

[Page 497]

To ensure proper encapsulation, all data in class MyShape must be private. This requires declaring proper set and get methods to manipulate the data. Class MyLine should provide a no-argument constructor and a constructor with arguments for the coordinates and color. Classes MyOval andMyRect should provide a no-argument constructor and a constructor with arguments for the coordinates, color and determining whether the shape is filled. The no-argument constructor should, in addition to setting the default values, set the shape to be an unfilled shape.

You can draw lines, rectangles and ovals if you know two points in space. Lines require x1 , y1 , x2 and y2 coordinates. The drawLine method of theGraphics class will connect the two points supplied with a line. If you have the same four coordinate values ( x1 , y1 , x2 and y2 ) for ovals and rectangles, you can calculate the four arguments needed to draw them. Each requires an upper-left x -coordinate value (the smaller of the two x -coordinate values), an upper-left y -coordinate value (the smaller of the two y coordinate values), a width (the absolute value of the difference between the two x -coordinate values) and a height (the absolute value of the difference between the two y -coordinate values). Rectangles and ovals should also have a filled flag that determines whether to draw the shape as a filled shape.

There should be no MyLine , MyOval or MyRectangle variables in the programonly MyShape variables that contain references to MyLine , MyOvaland MyRectangle objects. The program should generate random shapes and store them in an array of type MyShape . Method paintComponentshould walk through the MyShape array and draw every shape (i.e., polymorphically calling every shape's draw method).

Allow the user to specify (via an input dialog) the number of shapes to generate. The program will then generate and display the shapes along with a status bar that informs the user how many of each shape were created.

public class MyShape {

private int x1, y1, x2, y2;

public MyShape()
{
    this.setX1(0);
    this.setY1(0);
    this.setX2(0);
    this. setY2(0);
}

public MyShape(int x1, int y1, int x2, int y2 )
{
    setX1(x1);
    setY1(y1);
    setX2(x2);
    setY2(y2);
}

public void setX1(int x1)
{
if(x1 >= 0 && x1 <= 300)
{ this.x1 = x1;}
else
{this.x1 = 0;}
}

public int getX1()
{ return x1;}

public void setY1(int y1)
{
if(y1 >= 0 && y1 <= 300)
{ this.y1 = y1; }
else
{ this.y1 = 0; }
}

public int getY1()
{ return y1;}

public void setX2(int x2)
{
if(x2 >= 0 && x2 <= 300)
{ this.x2 = x2; }
else
{ this.x2 = 0; }
}

public int getX2()
{ return x2; }

public void setY2(int y2)
{
if(y2 >= 0 && y2 <= 300)
{ this.y2 = y2; }
else
{ this.y2 = 0; }
}

public int getY2()
{ return y2; }


public String toString()
{return String.format("(x1,y1): (%d,%d) (x2,y2): (%d,%d)" ,this.getX1(), this.getX2(),
this.getY1(), this.getY2());
}

}

package Project3;
import java.awt.Color;
import java.awt.Graphics;
public class MyLine extends MyShape
{

private Color myColor; // color of this shape

// constructor initializes private vars with default values
public MyLine()
{
this( 0, 0, 0, 0, Color.BLACK ); // call constructor to set values
} // end MyLine no-argument constructor

// constructor with input values
public MyLine( int x1, int y1, int x2, int y2, Color color )
{
    super(x1,y1,x2,y2); //calls base class constructor
    setColor( color ); // set the color
} // end MyLine constructor

// set the color
public void setColor( Color color )
{
myColor = color;
} // end method setColor

// get the color
public Color getColor()
{
return myColor;
} // end method getColor

// draw the line in the specified color
public void draw( Graphics g )
{
g.setColor( getColor() );
g.drawLine( getX1(), getY1(), getX2(), getY2() );
} // end method draw

} // end class MyLine

package Project3;
import java.awt.Color;
import java.awt.Graphics;
public class MyOval extends MyShape {

private Color myColor; // Color of this oval
private boolean filled; // whether this shape is filled

// constructor initializes private vars with default values
public MyOval()
{
this( 0, 0, 0, 0, Color.BLACK, false ); // call constructor
} // end MyOval no-argument constructor

// constructor with input values
public MyOval( int x1, int y1, int x2, int y2,
Color color, boolean isFilled )
{
    super(x1,y1,x2,y2);
    setColor( color ); // set the color
    setFilled( isFilled );
} // end MyOval constructor

// set the x-coordinate of the first point

// set the color
public void setColor( Color color )
{
myColor = color;
} // end method setColor

//get the color
public Color getColor()
{
return myColor;
} // end method getColor

// get upper left x coordinate
public int getUpperLeftX()
{
return Math.min( getX1(), getX2() );
} // end method getUpperLeftX
// get upper left y coordinate
public int getUpperLeftY()
{
return Math.min( getY1(), getY2() );
} // end method getUpperLeftY

// get shape width
public int getWidth()
{
return Math.abs( getX2() - getX1() );
} // end method getWidth

// get shape height
public int getHeight()
{
return Math.abs( getY2() - getY1() );
} // end method getHeight

// determines whether this shape is filled
public boolean isFilled()
{
return filled;
} // end method is filled

// sets whether this shape is filled
public void setFilled( boolean isFilled )
{
filled = isFilled;
} // end method setFilled

// draws an oval in the specified color
public void draw( Graphics g )
{
g.setColor( getColor() );

if ( isFilled() )
g.fillOval( getUpperLeftX(), getUpperLeftY(),
getWidth(), getHeight() );
else
g.drawOval( getUpperLeftX(), getUpperLeftY(),
getWidth(), getHeight() );
} // end method draw
} // end class MyOval

package Project3;
import java.awt.Color;
import java.awt.Graphics;
public class MyRectangle extends MyShape {

private Color myColor; // Color of this rectangle
private boolean filled; // whether this shape is filled

// constructor initializes private vars with default values
public MyRectangle()
{
this( 0, 0, 0, 0, Color.BLACK, false ); // call constructor
} // end MyRect no-argument constructor

// constructor with input values
public MyRectangle( int x1, int y1, int x2, int y2,
Color color, boolean isFilled )
{
    super(x1,y1,x2,y2); //calls base class constructor
    setColor( color ); // set the color
    setFilled( isFilled );
} // end MyRect constructor

//sets color
public void setColor( Color color )
{
myColor = color;
} // end method setColor

// get the color
public Color getColor()
{
return myColor;
} // end method getColor

// get upper left x coordinate
public int getUpperLeftX()
{
return Math.min( getX1(), getX2() );
} // end method getUpperLeftX

// get upper left y coordinate
public int getUpperLeftY()
{
return Math.min( getY1(), getY2() );
} // end method getUpperLeftY

// get shape width
public int getWidth()
{
return Math.abs( getX2() - getX1() );
} // end method getWidth

// get shape height
public int getHeight()
{
return Math.abs( getY2() - getY1() );
} // end method getHeight

// determines whether this shape is filled
public boolean isFilled()
{
return filled;
} // end method is filled

// sets whether this shape is filled
public void setFilled( boolean isFilled )
{
filled = isFilled;
} // end method setFilled

// draws a rectangle in the specified color
public void draw( Graphics g )
{
g.setColor( getColor() );

if ( isFilled() )
g.fillRect( getUpperLeftX(), getUpperLeftY(),
getWidth(), getHeight() );
else
g.drawRect( getUpperLeftX(), getUpperLeftY(),
getWidth(), getHeight() );
} // end method draw
} // end class MyRect

package Project3;
import java.awt.Color;
import java.awt.Graphics;
import java.util.Random;
import javax.swing.JPanel;

public class DrawPanel extends JPanel
{
private Random randomNumbers = new Random();
private MyLine lines[]; // array on lines
private MyOval ovals[]; // array of ovals
private MyRectangle rectangles[]; // array of rectangles
// constructor, creates a panel with random shapes
public DrawPanel()
{
setBackground( Color.WHITE );
lines = new MyLine[ 1 + randomNumbers.nextInt( 5 ) ];
ovals = new MyOval[ 1 + randomNumbers.nextInt( 5 ) ];
rectangles = new MyRectangle[ 1 + randomNumbers.nextInt( 5 ) ];

// create lines
for ( int count = 0; count < lines.length; count++ )
{
// generate random coordinates
int x1 = randomNumbers.nextInt( 450 );
int y1 = randomNumbers.nextInt( 450 );
int x2 = randomNumbers.nextInt( 450 );
int y2 = randomNumbers.nextInt( 450 );
// generate a random color
Color color = new Color( randomNumbers.nextInt( 256 ),
randomNumbers.nextInt( 256 ), randomNumbers.nextInt( 256 ) );
// add the line to the list of lines to be displayed
lines[ count ] = new MyLine( x1, y1, x2, y2, color );
} // end for
// create ovals
for ( int count = 0; count < ovals.length; count++ )
{
// generate random coordinates
int x1 = randomNumbers.nextInt( 450 );
int y1 = randomNumbers.nextInt( 450 );
int x2 = randomNumbers.nextInt( 450 );
int y2 = randomNumbers.nextInt( 450 );
// generate a random color
Color color = new Color( randomNumbers.nextInt( 256 ),
randomNumbers.nextInt( 256 ), randomNumbers.nextInt( 256 ) );
// get filled property
boolean filled = randomNumbers.nextBoolean();
// add the line to the oval of ovals to be displayed
ovals[ count ] = new MyOval( x1, y1, x2, y2, color, filled );
} // end for
// create rectangles
for ( int count = 0; count < rectangles.length; count++ )
{
// generate random coordinates
int x1 = randomNumbers.nextInt( 450 );
int y1 = randomNumbers.nextInt( 450 );
int x2 = randomNumbers.nextInt( 450 );
int y2 = randomNumbers.nextInt( 450 );
// generate a random color
Color color = new Color( randomNumbers.nextInt( 256 ),
randomNumbers.nextInt( 256 ), randomNumbers.nextInt( 256 ) );
// get filled property
boolean filled = randomNumbers.nextBoolean();
// add the rectangle to the list of rectangles to be displayed
rectangles[ count ] = new MyRectangle( x1, y1, x2, y2, color, filled );
} // end for
} // end DrawPanel constructor
// for each shape array, draw the individual shapes
public void paintComponent( Graphics g )
{
super.paintComponent( g );
// draw the lines
for ( MyLine line : lines )
line.draw( g );
// draw the ovals
for ( MyOval oval: ovals )
oval.draw( g );
// drat the rectangles
for ( MyRectangle rectangle : rectangles )
rectangle.draw( g );
} // end method paintComponent

public String status()
{
// returns number of lines,ovals,rectangles which are drawn in the panel in a string format
return String.format("%s: %d, %s: %d, %s:%d", "lines",lines.length,"ovals",ovals.length,"rectangles",rectangles.length);
}
} // end class DrawPanel

package Project3;
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class TestDraw
{
public static void main(String[] args)
{
final int WINDOW_WIDTH = 400, WINDOW_HEIGHT = 400;
JFrame application = new JFrame (); // the window and its components
DrawPanel panel = new DrawPanel (); // call constructor creating MyLine objects
JLabel southLabel = new JLabel(panel.status());
application.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
application.add (panel);
application.setSize (WINDOW_WIDTH, WINDOW_HEIGHT);
application.setVisible (true); // show the window
application.add(southLabel, BorderLayout.SOUTH);
}
}

Explanation / Answer

Looks like you have the class hierarchy already defined. MyLine, MyOval, and MyRectangle are already child classes of MyShape. The only thing left is to make MyShape abstract to declare the draw() method.

public abstract class MyShape
{
// rest of MyShape class

public abstract void draw(Graphics g);
}

Now any instance of MyShape can be drawn because it must implement draw().

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