k1ngp1n99
asked on
ClassCastException when running my program
Heres the code for my program is takes in a file which contains data like this.
LINE 250 500 100 100
CIRCLE 50 100 75 77
RECTANGLE 100 40 50 77
END
This part of the program displays correctly. My problem is when using the Line,Circle,Rectangle classes to anchor the shapes onto my GUI correctly.
heres the original question instead of repeating myself.
https://www.experts-exchange.com/questions/20812032/Interface-to-tag-drawable-objects.html
this part causes the problems. Each shape class gives anchor points.
shapelist.add(new Line(10, 10));
shapelist.add(new Circle(50));
shapelist.add(new Rectangle(100, 50));
import java.io.*;
import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
import javax.swing.border.LineBor der;
import java.util.*;
public class Proto1 extends JComponent{
private static final int WIDTH=400;
private static final int HEIGHT=300;
private ArrayList shapelist = new ArrayList();
public Proto1(String filename){
this.setPreferredSize(new Dimension(WIDTH,HEIGHT));
this.setBorder(new LineBorder(Color.red,10));
shapelist.add(new Line(10, 10));
shapelist.add(new Circle(50));
shapelist.add(new Rectangle(100, 50));
try{
String line;
BufferedReader in = new BufferedReader(new FileReader (filename));
while(!(line=in.readLine() ).equals(" END"))
{
StringTokenizer st = new StringTokenizer(line);
String tok = st.nextToken();
if(tok.equals("LINE"))
{
shapelist.add(new Line2D.Float(
Integer.parseInt(st.nextTo ken()),
Integer.parseInt(st.nextTo ken()),
Integer.parseInt(st.nextTo ken()),
Integer.parseInt(st.nextTo ken())));
}
else if(tok.equals("CIRCLE"))
{
shapelist.add(new Ellipse2D.Double(
Integer.parseInt(st.nextTo ken()),
Integer.parseInt(st.nextTo ken()),
Integer.parseInt(st.nextTo ken()),
Integer.parseInt(st.nextTo ken())));
}
else if(tok.equals("RECTANGLE") )
{
shapelist.add(new Rectangle2D.Float(
Integer.parseInt(st.nextTo ken()),
Integer.parseInt(st.nextTo ken()),
Integer.parseInt(st.nextTo ken()),
Integer.parseInt(st.nextTo ken())));
}
}
in.close();
}
catch(IOException e)
{
System.out.println(e.getMe ssage());
}
}
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
for(int i=0;i< shapelist.size();i++)
{
Shape shape = (Shape) shapelist.get(i);
g2.setPaint(Color.blue);
g2.draw(shape);
g2.fill(shape);
repaint();
}
}
public static void main( String [] args ){
JFrame jWindow = new JFrame("Prototype 1");
jWindow.setDefaultCloseOpe ration(JFr ame.EXIT_O N_CLOSE);
jWindow.getContentPane().a dd(new Proto1(args[0]),BorderLayo ut.CENTER) ;
jWindow.pack();
jWindow.setVisible(true);
}
}
SHAPE CLASSES
// CIRCLE
import java.awt.geom.*; // enables use of Line2D
import java.awt.Graphics2D; // enables use of Graphics2D
class Circle implements Drawable
{
private int x; // anchor point, x
private int y; // anchor point, y
private int w; // width of circle
private int h; // height of circle
private int r; // radius of circle
public Circle(int r)
{
this.r = r; // store the radius value so it can be used in the draw method
w = r*2; // 2 times the radius gives you the length of the width
h = r*2; // 2 times the radius gives you the length of the height
}
public void draw(Graphics2D g, int ax, int ay)
{
x = ax-r; //anchor point - radius to give to give centre at anchor point
y = ay-r;
g.draw(new Ellipse2D.Float(x, y, w, h));
}
public String toString()
{
return "Circle: radius=" + r + " centre points (" + x + "," + y + ")";
}
}
// LINE
import java.awt.geom.*; // enables use of Line2D
import java.awt.Graphics2D; // enables use of Graphics2D
class Line implements Drawable
{
private int dx; // x displacement from the anchor point
private int dy; // y displacement from the anchor point
public Line(int x, int y) // anchor point starts at x, y
{
dx = x;
dy = y;
}
public void draw(Graphics2D g, int ax, int ay)
{
g.draw(new Line2D.Float(ax, ay, ax+dx, ay+dy));
}
public String toString()
{
return "Line: x-displacement=" + dx + " y-displacement=" + dy;
}
}
// RECTANGLE
import java.awt.geom.*; // enables use of Line2D
import java.awt.Graphics2D; // enables use of Graphics2D
class Rectangle implements Drawable
{
private int w;
private int h;
public Rectangle(int w, int h)
{
this.w =w;
this.h = h;
}
public void draw(Graphics2D g, int x, int y)
{
g.draw(new Rectangle2D.Float(x, y, w, h));
}
public String toString()
{
return "Rectangle: width=" + w + " height=" + h;
}
}
please ask for more code if needed.
LINE 250 500 100 100
CIRCLE 50 100 75 77
RECTANGLE 100 40 50 77
END
This part of the program displays correctly. My problem is when using the Line,Circle,Rectangle classes to anchor the shapes onto my GUI correctly.
heres the original question instead of repeating myself.
https://www.experts-exchange.com/questions/20812032/Interface-to-tag-drawable-objects.html
this part causes the problems. Each shape class gives anchor points.
shapelist.add(new Line(10, 10));
shapelist.add(new Circle(50));
shapelist.add(new Rectangle(100, 50));
import java.io.*;
import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
import javax.swing.border.LineBor
import java.util.*;
public class Proto1 extends JComponent{
private static final int WIDTH=400;
private static final int HEIGHT=300;
private ArrayList shapelist = new ArrayList();
public Proto1(String filename){
this.setPreferredSize(new Dimension(WIDTH,HEIGHT));
this.setBorder(new LineBorder(Color.red,10));
shapelist.add(new Line(10, 10));
shapelist.add(new Circle(50));
shapelist.add(new Rectangle(100, 50));
try{
String line;
BufferedReader in = new BufferedReader(new FileReader (filename));
while(!(line=in.readLine()
{
StringTokenizer st = new StringTokenizer(line);
String tok = st.nextToken();
if(tok.equals("LINE"))
{
shapelist.add(new Line2D.Float(
Integer.parseInt(st.nextTo
Integer.parseInt(st.nextTo
Integer.parseInt(st.nextTo
Integer.parseInt(st.nextTo
}
else if(tok.equals("CIRCLE"))
{
shapelist.add(new Ellipse2D.Double(
Integer.parseInt(st.nextTo
Integer.parseInt(st.nextTo
Integer.parseInt(st.nextTo
Integer.parseInt(st.nextTo
}
else if(tok.equals("RECTANGLE")
{
shapelist.add(new Rectangle2D.Float(
Integer.parseInt(st.nextTo
Integer.parseInt(st.nextTo
Integer.parseInt(st.nextTo
Integer.parseInt(st.nextTo
}
}
in.close();
}
catch(IOException e)
{
System.out.println(e.getMe
}
}
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
for(int i=0;i< shapelist.size();i++)
{
Shape shape = (Shape) shapelist.get(i);
g2.setPaint(Color.blue);
g2.draw(shape);
g2.fill(shape);
repaint();
}
}
public static void main( String [] args ){
JFrame jWindow = new JFrame("Prototype 1");
jWindow.setDefaultCloseOpe
jWindow.getContentPane().a
jWindow.pack();
jWindow.setVisible(true);
}
}
SHAPE CLASSES
// CIRCLE
import java.awt.geom.*; // enables use of Line2D
import java.awt.Graphics2D; // enables use of Graphics2D
class Circle implements Drawable
{
private int x; // anchor point, x
private int y; // anchor point, y
private int w; // width of circle
private int h; // height of circle
private int r; // radius of circle
public Circle(int r)
{
this.r = r; // store the radius value so it can be used in the draw method
w = r*2; // 2 times the radius gives you the length of the width
h = r*2; // 2 times the radius gives you the length of the height
}
public void draw(Graphics2D g, int ax, int ay)
{
x = ax-r; //anchor point - radius to give to give centre at anchor point
y = ay-r;
g.draw(new Ellipse2D.Float(x, y, w, h));
}
public String toString()
{
return "Circle: radius=" + r + " centre points (" + x + "," + y + ")";
}
}
// LINE
import java.awt.geom.*; // enables use of Line2D
import java.awt.Graphics2D; // enables use of Graphics2D
class Line implements Drawable
{
private int dx; // x displacement from the anchor point
private int dy; // y displacement from the anchor point
public Line(int x, int y) // anchor point starts at x, y
{
dx = x;
dy = y;
}
public void draw(Graphics2D g, int ax, int ay)
{
g.draw(new Line2D.Float(ax, ay, ax+dx, ay+dy));
}
public String toString()
{
return "Line: x-displacement=" + dx + " y-displacement=" + dy;
}
}
// RECTANGLE
import java.awt.geom.*; // enables use of Line2D
import java.awt.Graphics2D; // enables use of Graphics2D
class Rectangle implements Drawable
{
private int w;
private int h;
public Rectangle(int w, int h)
{
this.w =w;
this.h = h;
}
public void draw(Graphics2D g, int x, int y)
{
g.draw(new Rectangle2D.Float(x, y, w, h));
}
public String toString()
{
return "Rectangle: width=" + w + " height=" + h;
}
}
please ask for more code if needed.
if(tok.equals("LINE"))
{
shapelist.add(new Line2D.Float(
Integer.parseInt(st.nextTo ken()),
Integer.parseInt(st.nextTo ken()),
Integer.parseInt(st.nextTo ken()),
Integer.parseInt(st.nextTo ken())));
}
else if(tok.equals("CIRCLE"))
{
shapelist.add(new Ellipse2D.Double(
Integer.parseInt(st.nextTo ken()),
Integer.parseInt(st.nextTo ken()),
Integer.parseInt(st.nextTo ken()),
Integer.parseInt(st.nextTo ken())));
}
else if(tok.equals("RECTANGLE") )
{
shapelist.add(new Rectangle2D.Float(
Integer.parseInt(st.nextTo ken()),
Integer.parseInt(st.nextTo ken()),
Integer.parseInt(st.nextTo ken()),
Integer.parseInt(st.nextTo ken())));
}
You should be creating instances of your Drawable classes, and not Shape instances.
{
shapelist.add(new Line2D.Float(
Integer.parseInt(st.nextTo
Integer.parseInt(st.nextTo
Integer.parseInt(st.nextTo
Integer.parseInt(st.nextTo
}
else if(tok.equals("CIRCLE"))
{
shapelist.add(new Ellipse2D.Double(
Integer.parseInt(st.nextTo
Integer.parseInt(st.nextTo
Integer.parseInt(st.nextTo
Integer.parseInt(st.nextTo
}
else if(tok.equals("RECTANGLE")
{
shapelist.add(new Rectangle2D.Float(
Integer.parseInt(st.nextTo
Integer.parseInt(st.nextTo
Integer.parseInt(st.nextTo
Integer.parseInt(st.nextTo
}
You should be creating instances of your Drawable classes, and not Shape instances.
> Shape shape = (Shape) shapelist.get(i);
> g2.setPaint(Color.blue);
> g2.draw(shape);
> g2.fill(shape);
should be:
Drawable shape = (Drawable) shapelist.get(i);
g2.setPaint(Color.blue);
g2.draw(shape, 0, 0);
> g2.setPaint(Color.blue);
> g2.draw(shape);
> g2.fill(shape);
should be:
Drawable shape = (Drawable) shapelist.get(i);
g2.setPaint(Color.blue);
g2.draw(shape, 0, 0);
Alternatively if you want to support both Shape and Drawable just change your poaintComponent method to:
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
for(int i=0;i< shapelist.size();i++)
{
Object next = shapelist.get(i);
if (next instanceof Shape)
{
Shape shape = (Shape) g2.setPaint(Color.blue);
g2.draw(shape);
g2.fill(shape);
}
else if (next instanceof Drawable)
{
Drawable shape = (Drawable) next;
g2.draw(shape, 0, 0);
}
}
repaint();
}
That'll allow you to add both Shape and Drawable instances to your shapelist.
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
for(int i=0;i< shapelist.size();i++)
{
Object next = shapelist.get(i);
if (next instanceof Shape)
{
Shape shape = (Shape) g2.setPaint(Color.blue);
g2.draw(shape);
g2.fill(shape);
}
else if (next instanceof Drawable)
{
Drawable shape = (Drawable) next;
g2.draw(shape, 0, 0);
}
}
repaint();
}
That'll allow you to add both Shape and Drawable instances to your shapelist.
There's no need for a new interface called Drawable.
a. Shape is specifically designed so that various shapes of different types can be drawn on a graphics context
b. Creating subclasses of the library classes will mean that you're already implementing Shape anyway, so you won't have to do anything
e.g. with the LINE
class LINE extends Line2D.Float {
}
// add an instance to the list
Shape s = (Shape)shapeList.get(i);
a. Shape is specifically designed so that various shapes of different types can be drawn on a graphics context
b. Creating subclasses of the library classes will mean that you're already implementing Shape anyway, so you won't have to do anything
e.g. with the LINE
class LINE extends Line2D.Float {
}
// add an instance to the list
Shape s = (Shape)shapeList.get(i);
ASKER
objects i get this errors when i try to replace your paintcomponent method with what you said
>Alternatively if you want to support both Shape and Drawable just >change your poaintComponent method to:
C:\Documents and Settings\kingpin\My Documents\Work\Software construction\Project Draw\prototype2\My ****\Proto1.java:70: inconvertible types
found : void
required: java.awt.Shape
Shape shape = (Shape) g2.setPaint(Color.blue);
^
C:\Documents and Settings\kingpin\My Documents\Work\Software construction\Project Draw\prototype2\My ****\Proto1.java:77: draw(java.awt.Shape) in java.awt.Graphics2D cannot be applied to (Drawable,int,int)
g2.draw(shape, 0, 0);
>Alternatively if you want to support both Shape and Drawable just >change your poaintComponent method to:
C:\Documents and Settings\kingpin\My Documents\Work\Software construction\Project Draw\prototype2\My ****\Proto1.java:70: inconvertible types
found : void
required: java.awt.Shape
Shape shape = (Shape) g2.setPaint(Color.blue);
^
C:\Documents and Settings\kingpin\My Documents\Work\Software construction\Project Draw\prototype2\My ****\Proto1.java:77: draw(java.awt.Shape) in java.awt.Graphics2D cannot be applied to (Drawable,int,int)
g2.draw(shape, 0, 0);
sorry, my fault. try this:
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setPaint(Color.blue);
for(int i=0;i< shapelist.size();i++)
{
Object next = shapelist.get(i);
if (next instanceof Shape)
{
Shape shape = (Shape) next;
g2.draw(shape);
g2.fill(shape);
}
else if (next instanceof Drawable)
{
Drawable shape = (Drawable) next;
g2.draw(shape, 0, 0);
}
}
repaint();
}
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setPaint(Color.blue);
for(int i=0;i< shapelist.size();i++)
{
Object next = shapelist.get(i);
if (next instanceof Shape)
{
Shape shape = (Shape) next;
g2.draw(shape);
g2.fill(shape);
}
else if (next instanceof Drawable)
{
Drawable shape = (Drawable) next;
g2.draw(shape, 0, 0);
}
}
repaint();
}
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
objects that solves the first error but the other error still comes up.
That was a quick reply anyway.
C:\Documents and Settings\kingpin\My Documents\Work\Software construction\Project Draw\prototype2\My ****\Proto1.java:78: draw(java.awt.Shape) in java.awt.Graphics2D cannot be applied to (Drawable,int,int)
g2.draw(shape, 0, 0);
That was a quick reply anyway.
C:\Documents and Settings\kingpin\My Documents\Work\Software construction\Project Draw\prototype2\My ****\Proto1.java:78: draw(java.awt.Shape) in java.awt.Graphics2D cannot be applied to (Drawable,int,int)
g2.draw(shape, 0, 0);
ASKER
brilliant works a charm.
The shapes appear in the right places.
The shapes appear in the right places.
ASKER
objects could you please explaint this code to me. You gave me this code last time. Its from the question i linked to about creating a picture and pictureComponent class. A quick tip in implementing this would be helpful, because it seems to be correct from what ive read from the specification.
Points are yours ;)
Thanks again.
public class PictureComponent implements Drawable
{
private Drawable Shape = null;
private int X = 0;
private int Y = 0;
public PictureComponent(Drawable d, int x, int y)
{
D = d;
X = x;
Y = y;
}
public void draw(Graphics2D g, int ax, int ay)
{
D.draw(g, X+ax, Y+ay);
}
}
public class Picture implements Drawable
{
private ArrayList Drawables = new ArrayList();
public void addDrawable(Drawable d, int x, int y)
{
Drawables.add(new PictureComponent(d, x, y));
}
public void draw(Graphics2D g, int ax, int ay)
{
Iterator i = Drawables.iterator()
while (i.hasNext())
{
PictureComponent d = (Drawable) i.next();
g.draw(g, ax, ay);
}
}
Points are yours ;)
Thanks again.
public class PictureComponent implements Drawable
{
private Drawable Shape = null;
private int X = 0;
private int Y = 0;
public PictureComponent(Drawable d, int x, int y)
{
D = d;
X = x;
Y = y;
}
public void draw(Graphics2D g, int ax, int ay)
{
D.draw(g, X+ax, Y+ay);
}
}
public class Picture implements Drawable
{
private ArrayList Drawables = new ArrayList();
public void addDrawable(Drawable d, int x, int y)
{
Drawables.add(new PictureComponent(d, x, y));
}
public void draw(Graphics2D g, int ax, int ay)
{
Iterator i = Drawables.iterator()
while (i.hasNext())
{
PictureComponent d = (Drawable) i.next();
g.draw(g, ax, ay);
}
}
PictureComponent is a Drawable implementation that drfaws a Drawable instance at a specified offset.
Picture is a Drawable implementation that draws a list of Drawable's each at specified offsets.
Picture is a Drawable implementation that draws a list of Drawable's each at specified offsets.
As I mentioned in earlier posts, you would have only needed the interface Shape