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