Drawing from one class to another

creating a simple graphics program

  • (2 Pages)
  • +
  • 1
  • 2

17 Replies - 3924 Views - Last Post: 12 May 2009 - 11:50 AM Rate Topic: -----

#1 Charlie IronGleet  Icon User is offline

  • D.I.C Head

Reputation: 2
  • View blog
  • Posts: 225
  • Joined: 29-January 09

Drawing from one class to another

Posted 10 May 2009 - 11:08 AM

Hi,

I'm working on creating a simple graphics program. It must allow the user to select a line, triangle, rectangle, or circle along with some parameters and then draw the object onto a panel inside a GUI.

It's given me no end of frustration.

I've set up an inheritance hierarchy of classes for the shape, all of which extend BaseShape which itself extends JPanel.

The code I'm about to post is completed just to the point where the user ought to be able to select "Circle" from the combo box and then hit draw and a circle with hardcoded coordinates and parameters ought appear in the gui. It doesn't though.

I'd really appreciate it if one of you guys could take a few moments to explain where I'm going wrong. This is my last assignment due tommorow and I'd like to finish before the family comes over for mothers day.

Here's the code so far... Please note that things about the circle class might look strange because I've hardcoded the parameters into the call to it -- this just a test because right now all I want to know is how to grab the image from one of these class objects and throw it onto my interface. Hope I;ve explained the issue all right.

Many thanks...

import javax.swing.*;
import java.awt.Graphics;

public class BaseShape extends JPanel {

	private String shapeType;
	private Point point;

	public BaseShape() {

	}
	protected void paintComponent(Graphics g) {
		super.paintComponent(g);
	}
}

import javax.swing.*;
import java.awt.Graphics;
import java.awt.*;


public class Circle extends BaseShape{
	private Point center;
	private int width;
	private int height;
	private int x = 0;
	private int y = 0;

	public Circle(int x, int y, int width, int height) {
		this.center = center;
		this.width = width;
		this.height = height;
		this.x = x;
		this.y = y;
	}
	protected void paintComponent(Graphics g) {
		super.paintComponent(g);
		g.drawOval(x, y, width, height);
	}
}
import javax.swing.*;
import java.awt.Graphics;

public class Line extends BaseShape{
	private Point start;
	private Point end;

	public Line(Point start, Point end) {
		this.start = start;
		this.end = end;
	}
	protected void paintComponent(Graphics g) {
		super.paintComponent(g);
		g.drawLine(start.getX(), start.getY(), end.getX(), end.getY());
	}
}
import javax.swing.*;
import java.awt.Graphics;

public class Triangle extends BaseShape {
	private Point vertex1;
	private Point vertex2;
	private Point vertex3;

	public Triangle(Point vertex1, Point vertex2, Point vertex3) {
		this.vertex1 = vertex1;
		this.vertex2 = vertex2;
		this.vertex3 = vertex3;
	}
	protected void paintComponent(Graphics g) {
		super.paintComponent(g);
		g.drawLine(vertex1.getX(), vertex1.getY(), vertex2.getX(), vertex2.getY());
		g.drawLine(vertex2.getX(), vertex2.getY(), vertex3.getX(), vertex3.getY());
		g.drawLine(vertex1.getX(), vertex1.getY(), vertex3.getX(), vertex3.getY());
	}
}
import javax.swing.*;
import java.awt.Graphics;
import java.awt.*;

public class Rectangle extends BaseShape {
	private Point location;
	private int width;
	private int height;

	public Rectangle(Point location, int width, int height) {
		this.location = location;
		this.width = width;
		this.height = height;
	}
	protected void paintComponent(Graphics g) {
		super.paintComponent(g);
		g.drawRect(location.getX(), location.getY(), width, height);
	}
}
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.Graphics;
import javax.swing.JFrame;



public class CadGui extends JFrame {
	private JButton drawButton = new JButton("Draw Shape");
	private JButton eraseButton = new JButton("Erase Shape");
	private JButton saveButton = new JButton("Save as .gif");
	private String[] shape = { "Circle", "Rectangle", "Triangle", "Line" };
	private JComboBox jcbShape = new JComboBox(shape);
	private String[] size = { "small", "medium", "large" };
	private JComboBox jcbSize = new JComboBox(size);
	private String[] location = { "north", "south", "east", "center", "west" };
	private JComboBox jcbLocation = new JComboBox(location);
	private JPanel topPanel  = new JPanel();
	private JPanel bottomPanel = new JPanel();
	//private ImagePanel imagePanel = new ImagePanel();

	private int sizeChoice = 0;
	private Graphics canvasGraphics = bottomPanel.getGraphics();

	public CadGui() {
		setLayout(new BorderLayout());
		bottomPanel.setLayout(new BorderLayout());
		topPanel.add(drawButton);
		topPanel.add(jcbShape);
		topPanel.add(jcbSize);
		topPanel.add(jcbLocation);
		topPanel.add(saveButton);
		topPanel.add(eraseButton);
		add(topPanel, BorderLayout.NORTH);
		add(bottomPanel, BorderLayout.CENTER);
		setSize(640,480);
		setLocationRelativeTo(null);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setVisible(true);

		drawButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				bottomPanel.repaint();
			}
		});

		jcbShape.addItemListener(new ItemListener() {
			public void itemStateChanged(ItemEvent e) {
				int tempChoice = jcbShape.getSelectedIndex();
				switch(tempChoice) {
					case 0: circle();
								break;
					case 1: rectangle();
								break;
					case 2: triangle();
								 break;
					case 3: line();
								 break;
				}
			}
		});
		jcbSize.addItemListener(new ItemListener() {
			public void itemStateChanged(ItemEvent e) {
				sizeChoice = jcbSize.getSelectedIndex();
			}
		});
	}

	public void circle() {
	//
	}
	public void rectangle() {
		Circle tempCircle = new Circle(100,100,100,100);
		Graphics tempGraphics = tempCircle.getGraphics();
		canvasGraphics = tempGraphics;
	}
	public void triangle() {
	//
	}
	public void line() {
	//
	}
	protected void paintComponent(Graphics g) {
		super.paintComponent(g);

	}
}

public class CadApplication {
	public static void main(String[] args) {
		new CadGui();
	}
}


oh yeah, heres the point class. Never used so far but need it to compile
public class Point {

	private int x = 0;
	private int y = 0;

	public Point(int x, int y) {
		this.x = x;
		this.y = y;
	}
	public void setX(int x) {
		this.x = x;
	}
	public void setY(int y) {
		this.y = y;
	}
	public int getX() {
		return this.x;
	}
	public int getY() {
		return this.y;
	}
}

This post has been edited by Charlie IronGleet: 10 May 2009 - 11:34 AM


Is This A Good Question/Topic? 0
  • +

Replies To: Drawing from one class to another

#2 g00se  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 2639
  • View blog
  • Posts: 11,148
  • Joined: 20-September 08

Re: Drawing from one class to another

Posted 10 May 2009 - 02:12 PM

You've actually implemented the rectangle method with a circle, but never mind. Since you've implemented the shapes as JPanel subclasses, all you need do is add them:

    public void rectangle() {
        Circle tempCircle = new Circle(100,100,100,100);
        for(Component c : bottomPanel.getComponents()) {
            bottomPanel.remove();
        }
        bottomPanel.add(tempCircle);
        validate();
        repaint();
    }



btw there is already java,awt,Point, which is pretty much the same as yours

This post has been edited by g00se: 10 May 2009 - 02:15 PM

Was This Post Helpful? 1
  • +
  • -

#3 pbl  Icon User is offline

  • There is nothing you can't do with a JTable
  • member icon

Reputation: 8324
  • View blog
  • Posts: 31,857
  • Joined: 06-March 08

Re: Drawing from one class to another

Posted 10 May 2009 - 06:39 PM

View Postg00se, on 10 May, 2009 - 01:12 PM, said:

You've actually implemented the rectangle method with a circle, but never mind. Since you've implemented the shapes as JPanel subclasses, all you need do is add them:

    public void rectangle() {
        Circle tempCircle = new Circle(100,100,100,100);
        for(Component c : bottomPanel.getComponents()) {
            bottomPanel.remove();
        }
        bottomPanel.add(tempCircle);
        validate();
        repaint();
    }



btw there is already java,awt,Point, which is pretty much the same as yours

Oups GOOse this as a level of abstraction that I can't follow. Are you telling me I am due to retirement ?
Was This Post Helpful? 1
  • +
  • -

#4 Charlie IronGleet  Icon User is offline

  • D.I.C Head

Reputation: 2
  • View blog
  • Posts: 225
  • Joined: 29-January 09

Re: Drawing from one class to another

Posted 11 May 2009 - 07:49 PM

View Postpbl, on 10 May, 2009 - 05:39 PM, said:

View Postg00se, on 10 May, 2009 - 01:12 PM, said:

You've actually implemented the rectangle method with a circle, but never mind. Since you've implemented the shapes as JPanel subclasses, all you need do is add them:

    public void rectangle() {
        Circle tempCircle = new Circle(100,100,100,100);
        for(Component c : bottomPanel.getComponents()) {
            bottomPanel.remove();
        }
        bottomPanel.add(tempCircle);
        validate();
        repaint();
    }



btw there is already java,awt,Point, which is pretty much the same as yours

Oups GOOse this as a level of abstraction that I can't follow. Are you telling me I am due to retirement ?


Thanks -- 2 Questions on this:

FIRST:
-- right there you did something I have been struggling to figure out for a while., about how to add and remove JPanels. I can't follow your code at all though. The 'for .....' is totally unfamiliar. Could you explain it, break it down for me? If this has him looking towards retirement, imagine how a lowly dichead must feel!!


SECOND:
My Professor gave us an extension today because everyone did this with JPanels and he wanted it done without the shape classes extending JPanel. Also, one of the specs was to use polymorphism ( which I'd thought I had ) but he explained true polymorphism requires an interface or an abstract class at the top of my shape hierarchy.

I have tried just about every variation I can on these concepts and have churned out a bunch of code, some of which even compiles, but none of which actually draws an object to the screen. This should be easy -- I must be missing something truly stupid.

I know the solution lies in drawing to a graphics context g instead of a Jpanel and then passing it, and that the paintComponent methods in each shape class are superfluous now since they wont be extending JPanel -- I just can't figure out how to implement this design.

Hope you can help,
IronGleet

This post has been edited by Charlie IronGleet: 11 May 2009 - 07:59 PM

Was This Post Helpful? 0
  • +
  • -

#5 pbl  Icon User is offline

  • There is nothing you can't do with a JTable
  • member icon

Reputation: 8324
  • View blog
  • Posts: 31,857
  • Joined: 06-March 08

Re: Drawing from one class to another

Posted 11 May 2009 - 08:16 PM

View PostCharlie IronGleet, on 11 May, 2009 - 06:49 PM, said:

FIRST:
-- right there you did something I have been struggling to figure out for a while., about how to add and remove JPanels. I can't follow your code at all though. The 'for .....' is totally unfamiliar. Could you explain it, break it down for me? If this has him looking towards retirement, imagine how a lowly dichead must feel!!

Never a good idea to "remove" a JComponent you can make the LayoutManager become crazy if you do not know for sure what you are doing
Never seen an application where this was really required... there are always better workarounds like component.setVisible(false) a lot more safier
Was This Post Helpful? 0
  • +
  • -

#6 pbl  Icon User is offline

  • There is nothing you can't do with a JTable
  • member icon

Reputation: 8324
  • View blog
  • Posts: 31,857
  • Joined: 06-March 08

Re: Drawing from one class to another

Posted 11 May 2009 - 08:26 PM

View PostCharlie IronGleet, on 11 May, 2009 - 06:49 PM, said:

SECOND:
My Professor gave us an extension today because everyone did this with JPanels and he wanted it done without the shape classes extending JPanel.

I can see his point

View PostCharlie IronGleet, on 11 May, 2009 - 06:49 PM, said:

Also, one of the specs was to use polymorphism ( which I'd thought I had ) but he explained true polymorphism requires an interface or an abstract class at the top of my shape hierarchy.

Sorry but this is exactly why polymorphism was invented for: to avoid requiring an interface or an abstract class at the top of the class hierarchy.
He his telling you that class Polygon has to know what a rectangle is so that the class Polynom has to have a constructor with width and height and that the class Polynom has to know what a trapeze is and has to have a constructor having small base, large base and height as parameters.... do I need to continue ?

Or you misunderstood your teacher requirements or he his better going teach music or fine arts :)
Was This Post Helpful? 0
  • +
  • -

#7 Charlie IronGleet  Icon User is offline

  • D.I.C Head

Reputation: 2
  • View blog
  • Posts: 225
  • Joined: 29-January 09

Re: Drawing from one class to another

Posted 11 May 2009 - 08:33 PM

View Postpbl, on 11 May, 2009 - 07:26 PM, said:

View PostCharlie IronGleet, on 11 May, 2009 - 06:49 PM, said:

SECOND:
My Professor gave us an extension today because everyone did this with JPanels and he wanted it done without the shape classes extending JPanel.

I can see his point

View PostCharlie IronGleet, on 11 May, 2009 - 06:49 PM, said:

Also, one of the specs was to use polymorphism ( which I'd thought I had ) but he explained true polymorphism requires an interface or an abstract class at the top of my shape hierarchy.

Sorry but this is exactly why polymorphism was invented for: to avoid requiring an interface or an abstract class at the top of the class hierarchy.
He his telling you that class Polygon has to know what a rectangle is so that the class Polynom has to have a constructor with width and height and that the class Polynom has to know what a trapeze is and has to have a constructor having small base, large base and height as parameters.... do I need to continue ?

Or you misunderstood your teacher requirements or he his better going teach music or fine arts :)


He was *very* explicit -- 'true polymorphism' requires abstract classes or interfaces. I disagreed and many of us were confused. Can you clarify for me why you disagree? I get an inkling of what you are saying based on the error reports I've had in some of my experiments but if you could break it down for me in a little more detail it would prepare me to at least have some good questions formulated when I return to class.

Does it help if I add this: he also mentioned that abstract class or interface was necessary in order to take advantage of dynamic binding. But that just is polymorphism, right, so we're left with the same unresolved issue?? Plus, he said if we used abstract class, then it would just have to have two abstract methods, a draw shape and an erase shape method.


Utterly perplexed but...
Thanks again!
IronGleet

This post has been edited by Charlie IronGleet: 11 May 2009 - 08:40 PM

Was This Post Helpful? 0
  • +
  • -

#8 pbl  Icon User is offline

  • There is nothing you can't do with a JTable
  • member icon

Reputation: 8324
  • View blog
  • Posts: 31,857
  • Joined: 06-March 08

Re: Drawing from one class to another

Posted 11 May 2009 - 08:48 PM

View PostCharlie IronGleet, on 11 May, 2009 - 07:33 PM, said:

He was *very* explicit -- 'true polymorphism' requires abstract classes or interfaces. I disagreed and many of us were confused. Can you clarify for me why you disagree? I get an inkling of what you are saying based on the error reports I've had in some of my experiments but if you could break it down for me in a little more detail it would prepare me to at least have some good questions formulated when I return to class.

Ya !!! I understand ... you cannot go see your teacher tomorrow and tell him "A guru at DIC told me you are not knowing what you are talking about :D "

OK where does he want to implement polymorphism ?

If you have an Abstract class Animal that contains the average age of an Animal as instance variable

abstract class Animal {
   int averageAge;
   // constructor
   Animal(int age) {
	   averageAge = age;
	}



now you create the class Vertebre ... what ever is the English word for animals with bones you can have

class Vertebre extends Animal {
	 int nbBones;
	 // constructor
	 Vertebre(int age, int nbBones) {
	  



and your teacher is telling us that Animal must have a constructor for Animal(int age, int nbBones) ?
Or I really don't understandyour teacher requirements or you mistransfered them

This post has been edited by pbl: 11 May 2009 - 08:51 PM

Was This Post Helpful? 1
  • +
  • -

#9 g00se  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 2639
  • View blog
  • Posts: 11,148
  • Joined: 20-September 08

Re: Drawing from one class to another

Posted 12 May 2009 - 01:08 AM

Phew! Quite a lot of posting here: where would you like me to start?

The point about my recommendation is to take things up from what you've done - not advocate an approach. My purpose is to fix your problem. I'm not advocating adding and removing components at runtime. There are already implementations for most shapes in the JDK that can be painted by Graphics or Graphics2D

The for loop simply removes any existing components
Was This Post Helpful? 0
  • +
  • -

#10 Charlie IronGleet  Icon User is offline

  • D.I.C Head

Reputation: 2
  • View blog
  • Posts: 225
  • Joined: 29-January 09

Re: Drawing from one class to another

Posted 12 May 2009 - 04:34 AM

OK where does he want to implement polymorphism ?

If you have an Abstract class Animal that contains the average age of an Animal as instance variable

abstract class Animal {
   int averageAge;
   // constructor
   Animal(int age) {
	   averageAge = age;
	}



now you create the class Vertebre ... what ever is the English word for animals with bones you can have

class Vertebre extends Animal {
	 int nbBones;
	 // constructor
	 Vertebre(int age, int nbBones) {
	  what I



and your teacher is telling us that Animal must have a constructor for Animal(int age, int nbBones) ?
Or I really don't understandyour teacher requirements or you mistransfered them
[/quote]


I'm not sure. Until I can talk with him tomorrow, I'm trying to focus just on how to accomplish the following:

Use the hierarchy of shape classes (w/o abstract classes) in such a way ( remember, no JPanels) that I can, for example, instantiate a circle and then somehow, from inside my CadGui class ( or elsewhere if it isn't possible there ) get it to display on the one JPanel (bottomPanel in CadGui) that he wants us to draw on. I have no problem writing a simple single class program with a main method to draw something on a jpanel -- its when the drawing is done in one class and then another class is used to display that drawing -- that's my stumbling block.

If you could demonstrate the technique for me with one simple concrete class with all the parameters hardcoded in so that, for example, pressing draw would make a circle appear in the GUI, I could create my own inheritance hierarchy (w/o abstract classes) and use that to at least have a completed program to turn in. (Since tomorow is the last day of class, I can afford to lose a few points over the polymorphism issue and can clarify the issue with him then. He does know his stuff, wrote switching systems in Java for the phone company, maybe 10-15 yrs+ exp. Still, I know he said what he said.)

Thanks alot for your help!!
IronGleet

This post has been edited by Charlie IronGleet: 12 May 2009 - 04:37 AM

Was This Post Helpful? 0
  • +
  • -

#11 Charlie IronGleet  Icon User is offline

  • D.I.C Head

Reputation: 2
  • View blog
  • Posts: 225
  • Joined: 29-January 09

Re: Drawing from one class to another

Posted 12 May 2009 - 04:46 AM

View Postg00se, on 12 May, 2009 - 12:08 AM, said:

Phew! Quite a lot of posting here: where would you like me to start?

The point about my recommendation is to take things up from what you've done - not advocate an approach. My purpose is to fix your problem. I'm not advocating adding and removing components at runtime. There are already implementations for most shapes in the JDK that can be painted by Graphics or Graphics2D

The for loop simply removes any existing components


Yeah, I guess I was kind of all over the place. I narrowed my focus down for now in my last post, in my reply to pbl. Its the painting of shapes by the Graphics class that I'm stumped on. Not the simplest, draw a line on a JPanel one class with a main method demonstration program. I can do that. My issue is when I try to do something like this, as I was saying to pbl:

My CadGui class handles the interface for the program and contains a JPanel 'bottomPanel' that I want to draw to. To make things simpler, lets say all I want to accomplish is to have a circle appear when I hit the draw button ( to make it even simpler, hardcode the circle parameters - don't get them from user input ). Forget the abstract classes too. How would I instantiate a concrete circle class from within CadGui and then place that circle object onto the bottomPanel?

If I remember right, my instructor hinted that it involves painting just to a graphics context in the circle class and then drawing that context on a panel from some other class.

So it's this stuff with the graphics context, and paint, repaint, and paintComponent thats confusing me.

Thanks,
IronGleet
Was This Post Helpful? 0
  • +
  • -

#12 g00se  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 2639
  • View blog
  • Posts: 11,148
  • Joined: 20-September 08

Re: Drawing from one class to another

Posted 12 May 2009 - 05:13 AM

You already have the Shape interface in the JDK (essentially the same as an abstract class for the purposes of this discussion). There are various implementations (see docs) for all of the important geometric figures. The Graphics2D class knows how to paint all Shape instances. That's all you need
Was This Post Helpful? 0
  • +
  • -

#13 Charlie IronGleet  Icon User is offline

  • D.I.C Head

Reputation: 2
  • View blog
  • Posts: 225
  • Joined: 29-January 09

Re: Drawing from one class to another

Posted 12 May 2009 - 07:57 AM

View Postg00se, on 12 May, 2009 - 04:13 AM, said:

You already have the Shape interface in the JDK (essentially the same as an abstract class for the purposes of this discussion). There are various implementations (see docs) for all of the important geometric figures. The Graphics2D class knows how to paint all Shape instances. That's all you need

The point of the exercise - as this homework - is to do it ourselves.

so thanks....
Was This Post Helpful? 0
  • +
  • -

#14 g00se  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 2639
  • View blog
  • Posts: 11,148
  • Joined: 20-September 08

Re: Drawing from one class to another

Posted 12 May 2009 - 08:17 AM

Dont' worry - there'll be plenty of work to do - even if you do use the existing Shape implementations ;-)
Was This Post Helpful? 1
  • +
  • -

#15 Charlie IronGleet  Icon User is offline

  • D.I.C Head

Reputation: 2
  • View blog
  • Posts: 225
  • Joined: 29-January 09

Re: Drawing from one class to another

Posted 12 May 2009 - 11:04 AM

View Postg00se, on 12 May, 2009 - 07:17 AM, said:

Dont' worry - there'll be plenty of work to do - even if you do use the existing Shape implementations ;-)


I know how to use the existing shape implimentations, as I said. And we have to use the Graphics class. I assume you're referring to drawOval() darRect() drawLine... etc. etc.

Here is my hang-up that I can't get past -- and I have been busting my ass. I can set up a simple program like the following
[code]
public class Circle {
private x;

}
Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2