Shapes

An example demonstrating inheritance, polymorphism, graphics and components. The shapes are generated using random parameters. The classes MyLine, MyRect and MyOval extend the base class MyShape, which provides the basic variables and methods.
// Public Class MyLine
//
/*
-------------------------------
+ MyLine extends MyShape
-------------------------------

-------------------------------
+ MyLine() : n.a.
+ MyLine(double,double,double,double) : n.a.
+ getPerimeter() : double
+ getArea() : double
+ draw(Graphics) : void
+ fill(Graphics) : void
+ toString() : String
-------------------------------
*/
import java.awt.Graphics;
import java.awt.*;

public class MyLine extends MyShape{

   public MyLine(){ super();}

   public MyLine(double x1Val, double y1Val, double x2Val, double y2Val){
      super(x1Val, y1Val, x2Val, y2Val);
   }

   public double getPerimeter(){
      double x1=super.getX1();
      double y1=super.getY1();
      double x2=super.getX2();
      double y2=super.getY2();
      return Math.sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
   }

   public double getArea(){ return 0;}

   public void draw(Graphics g){
      final int mt=100,ml=25;           // top and left margins
      // draw shape
      g.drawLine(getIX1()+ml,getIY1()+mt,getIX2()+ml,getIY2()+mt);
   }

   public void fill(Graphics g){        // dummy routine for Lines
      final int mt=100,ml=25;           // top and left margins
      // draw shape
      g.drawLine(getIX1()+ml,getIY1()+mt,getIX2()+ml,getIY2()+mt);
   }

   public String toString(){
      String out="Line:\n";
      out+=super.toString();
      out+="Length = "+d2.format(getPerimeter())+"\n";
      return out;
   }

} // end MyLine

// Public Class MyRectangle
//
/*
-------------------------------
+ MyRectangle extends MyBoundedShape
-------------------------------

-------------------------------
+ MyRectangle() : n.a.
+ MyRectangle(double,double,double,double) : n.a.
+ getPerimeter() : double
+ getArea() : double
+ draw(Graphics) : void
+ fill(Graphics) : void
+ toString() : String
-------------------------------
*/
import java.awt.Graphics;
import java.awt.*;

public class MyRectangle extends MyBoundedShape{

   public MyRectangle(){ super();}

   public MyRectangle(double x1Val, double y1Val, double x2Val, double y2Val){
      super(x1Val, y1Val, x2Val, y2Val);
   }

   public double getPerimeter(){
      return 2*(super.getX2()-super.getX1())+2*(super.getY2()-super.getY1());
   }

   public double getArea(){
      return (super.getX2()-super.getX1())*(super.getY2()-super.getY1());
   }

   public void draw(Graphics g){
      final int mt=100,ml=25;           // top and left margins
      // draw shape
      g.drawRect(getIX1()+ml,getIY1()+mt,getWidth()+ml,getHeight()+mt);
   }

   public void fill(Graphics g){
      final int mt=100,ml=25;           // top and left margins
      // draw shape
      g.fillRect(getIX1()+ml,getIY1()+mt,getWidth()+ml,getHeight()+mt);
   }

   public String toString(){
      String out="Rectangle:\n";
      out+=super.toString();
      out+="Width  = "+d2.format(getX2()-getX1())+"\n";
      out+="Height = "+d2.format(getY2()-getY1())+"\n";
      out+="Permimeter = "+d2.format(getPerimeter())+"\n";
      out+="Area = "+d2.format(getArea())+"\n";
      return out;
   }

}  // end MyRectangle

// Public Class MyOval
//
/*
-------------------------------
+ MyOval extends MyBoundedShape
-------------------------------

-------------------------------
+ MyOval() : n.a.
+ MyOval(double,double,double,double) : n.a.
- getA() : double
- getB() : double
+ getPerimeter() : double
+ getArea() : double
+ draw(Graphics) : void
+ fill(Graphics) : void
+ toString() : String
-------------------------------
*/
import java.awt.Graphics;
import java.awt.*;

public class MyOval extends MyBoundedShape{

   public MyOval(){ super();}

   public MyOval(double x1Val, double y1Val, double x2Val, double y2Val){
      super(x1Val, y1Val, x2Val, y2Val);
   }

   private double getA(){return (getX2()-getX1())/2;}

   private double getB(){return (getY2()-getY1())/2;}

   public double getPerimeter(){
      // Approximation to perimeter of ellipse by Ramanujan's 1914 formula
      // P=pi*(a+b)*(1+3*h/(10+sqrt(4-3*h))) where h=(a-b)**2/(a+b)**2
      // ref: http://home.att.net/-numericana/answer/ellipse.htm
      double a=getA();
      double b=getB();
      // Note: equations are symmetric with respect to a, b
      double h=Math.pow((a-b)/(a+b),2);
      return Math.PI*(a+b)*(1+3*h/(10+Math.sqrt(4-3*h)));
   }

   public double getArea(){   // A=pi*a*b
      return Math.PI*getA()*getB();
   }

   public void draw(Graphics g){
      final int mt=100,ml=25;           // top and left margins
      // draw shape
      g.drawOval(getIX1()+ml,getIY1()+mt,getWidth()+ml,getHeight()+mt);
   }

   public void fill(Graphics g){
      final int mt=100,ml=25;           // top and left margins
      // draw shape
      g.fillOval(getIX1()+ml,getIY1()+mt,getWidth()+ml,getHeight()+mt);
   }

   public String toString(){
      String out="Ellipse:\n";
      out+=super.toString();
      out+="a = "+d2.format(getA())+"\n";
      out+="b = "+d2.format(getB())+"\n";
      out+="Permimeter = "+d2.format(getPerimeter())+"\n";
      out+="Area = "+d2.format(getArea())+"\n";
      return out;
   }

}  // end MyOval


// shape driver, P.C. 2004-10-16
//
import java.awt.*;
import java.awt.Graphics;
import java.awt.event.*;
import java.awt.Color;
import javax.swing.*;

public class Shape extends JApplet implements ActionListener{
   JButton bDraw;       // the DRAW button
   JLabel lNum;         // for input of number of shapes to be drawn
   JTextField tNum;
   JCheckBox cFill;     // for filling shapes
   JCheckBox cPastel;   // for pastel colours
   JCheckBox cArea;     // for text output of areas
   int nShapes;         // number of shapes to be drawn
   MyShape Shapes[];    // array of shapes to be drawn
   int px=400, py=550;  // size of display panel

   public void init(){
      // super("Shapes");
      // Get pane
      Container c=getContentPane();
      // specify FlowLayout for Pane
      c.setLayout(new FlowLayout());
      nShapes=3;
      Shapes=new MyShape[nShapes];
      Shapes[0]=new MyLine(20,20,120,130);
      Shapes[1]=new MyLine(30,25,140,130);
      Shapes[2]=new MyLine(35,40,125,155);

      // add checkboxes
      cFill=new JCheckBox("Fill");
      c.add(cFill);
      cPastel=new JCheckBox("Pastel Colours");
      c.add(cPastel);
      cArea=new JCheckBox("Area/Perimeter");
      c.add(cArea);

      // add text field
      lNum=new JLabel("      Number of objects");
      tNum=new JTextField(6);
      c.add(lNum); c.add(tNum);

      // button to begin calculations
      bDraw=new JButton("Draw");
      bDraw.addActionListener(this);
      c.add(bDraw);
      setSize(px,py);
      setVisible(true);
   }

   private void PopulateShapes(){
      int MaxShapes=3;                 // number of shapes available
      double xm=px-80, ym=py-210;      // size limit of shapes
      nShapes=Integer.parseInt(tNum.getText());
      nShapes=(nShapes > 0)?nShapes:10;
      Shapes=new MyShape[nShapes];
      for(int i=0;i < Shapes; i++ ){
         int k=(int)((double)MaxShapes*Math.random());  // Varies from 0 to MaxShapes-1
         switch(k){
            case 0: // line
               Shapes[i]=new MyLine(xm*Math.random(),ym*Math.random(),xm*Math.random(),ym*Math.random());
               break;
            case 1:  // rectangle
               Shapes[i]=new MyRectangle(xm*Math.random(),ym*Math.random(),xm*Math.random(),ym*Math.random());
               break;
            case 2:  // Oval
               Shapes[i]=new MyOval(xm*Math.random(),ym*Math.random(),xm*Math.random(),ym*Math.random());
               break;
         }
      }
   }

   private int RC(){       // Random Colours
      int colourBase=0;    // Normal Colours
      // Pastel Colours between 120 and 255
      if(cPastel.isSelected()){
         colourBase=120;   // Pastel Colours
      }
      return (int)(Math.random()*(255-colourBase)+colourBase);
   }

   public void actionPerformed(ActionEvent event){
      String out="";
      PopulateShapes();
      Graphics g=this.getGraphics();         // get graphics object
      for(int i=0;i < nShapes;i++){
         Color c=new Color(RC(),RC(),RC());  // Random Colours
         g.setColor(c); // set plotting colour
         if(cFill.isSelected()){
            Shapes[i].fill(g);
         } else {
            Shapes[i].draw(g);
         }
         out+="\nShape "+i+" ";
         out+=Shapes[i].toString();
      }
      if(cArea.isSelected()){
         JTextArea outArea = new JTextArea (25,20);
         outArea.setFont(new Font("Courier",Font.BOLD,16));
         JScrollPane scroller = new JScrollPane(outArea);
         outArea.setText(out);
         JOptionPane.showMessageDialog(null,scroller,"Shape details",JOptionPane.INFORMATION_MESSAGE);
      }
   }
} // end Shape