accessing a variable from another class

Very simple question but I can't do it. I have 3 classes:

DrawCircle class

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

class DrawCircle extends JPanel
{
    private int w, h, di, diBig, diSmall, maxRad, xSq, ySq, xPoint, yPoint;
    public DrawFrame d;

    public DrawCircle()
    {
        w = 400;
        h = 400;
        diBig = 300;
        diSmall = 10;
        maxRad = (diBig/2) - diSmall;
        xSq = 50;
        ySq = 50;
        xPoint = 200;
        yPoint = 200;
    }

    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        g.setColor(Color.blue);
        g.drawOval(xSq, ySq, diBig, diBig);

        for(int y=ySq; y<ySq+diBig; y=y+diSmall*2)
        {
            for(int x=xSq; x<w-xSq; x=x+diSmall)
            {
                if(Math.sqrt(Math.pow(yPoint-y,2) + Math.pow(xPoint-x, 2))<= maxRad)
                    {
                        g.drawOval(x, y, diSmall, diSmall);
                    }               
            }
        }

        for(int y=ySq+10; y<ySq+diBig; y=y+diSmall*2)
        {
            for(int x=xSq+5; x<w-xSq; x=x+diSmall)
            {
                if(Math.sqrt(Math.pow(yPoint-y,2) + Math.pow(xPoint-x, 2))<= maxRad)
                {
                    g.drawOval(x, y, diSmall, diSmall);
                }   
            }
        }
    }
}

DrawFrame class

public class DrawFrame extends JFrame
{
    public DrawFrame()
    {
        int width = 400;
        int height = 400;

        setTitle("Frame");
        setSize(width, height);

        addWindowListener(new WindowAdapter()
        {
            public void windowClosing(WindowEvent e)
            {
                System.exit(0);
            }
        });

        Container contentPane = getContentPane();
        contentPane.add(new DrawCircle());
    }
}

CircMain class

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

public class CircMain 
{
    public static void main(String[] args)
    {
        JFrame frame = new DrawFrame();
        frame.show();
    }
}

One class creates a frame, the other draws a circle and fills it with smaller circles. In DrawFrame I set width and height. In DrawCircle I need to access the width and height of DrawFrame. How do I do this?

I've tried making an object and tried using .getWidth and .getHeight but can't get it to work. I need specific code here because I've tried a lot of things but can't get it to work. Am I declaring width and height wrong in DrawFrame? Am creating the object the wrong way in DrawCircle?

Also, the variables i use in DrawCircle, should I have them in the constructor or not?


Solution 1:

You could make the variables public fields:

  public int width;
  public int height;

  DrawFrame() {
    this.width = 400;
    this.height = 400;
  }

You could then access the variables like so:

DrawFrame frame = new DrawFrame();
int theWidth = frame.width;
int theHeight = frame.height;

A better solution, however, would be to make the variables private fields add two accessor methods to your class, keeping the data in the DrawFrame class encapsulated:

 private int width;
 private int height;

 DrawFrame() {
    this.width = 400;
    this.height = 400;
 }

  public int getWidth() {
     return this.width;
  }

  public int getHeight() {
     return this.height;
  }

Then you can get the width/height like so:

  DrawFrame frame = new DrawFrame();
  int theWidth = frame.getWidth();
  int theHeight = frame.getHeight();

I strongly suggest you use the latter method.

Solution 2:

I had the same problem. In order to modify variables from different classes, I made them extend the class they were to modify. I also made the super class's variables static so they can be changed by anything that inherits them. I also made them protected for more flexibility.

Source: Bad experiences. Good lessons.

Solution 3:

I've tried making an object and tried using .getWidth and .getHeight but can't get it to work.

That´s because you are not setting the width and height fields in JFrame, but you are setting them on local variables. Fields HEIGHT and WIDTH are inhereted from ImageObserver

Fields inherited from interface java.awt.image.ImageObserver
ABORT, ALLBITS, ERROR, FRAMEBITS, HEIGHT, PROPERTIES, SOMEBITS, WIDTH

See http://java.sun.com/javase/6/docs/api/javax/swing/JFrame.html

If width and height represent state of the frame, then you could refactorize them to fields, and write getters for them.

Then, you could create a Constructor that receives both values as parameters

public class DrawFrame extends JFrame {
 private int width;
 private int height;

 DrawFrame(int _width, int _height){

   this.width = _width;
   this.height = _height;

   //other stuff here
}
 public int getWidth(){}
 public int getHeight(){}

 //other methods
}

If widht and height are going to be constant (after created) then you should use the final modifier. This way, once they are assigned a value, they can´t be modified.

Also, the variables i use in DrawCircle, should I have them in the constructor or not?

The way it is writen now, will only allow you to create one type of circle. If you wan´t to create different circles, you should overload the constructor with one with arguments).

For example, if you want to change the attributes xPoint and yPoint, you could have a constructor

public DrawCircle(int _xpoint, int _ypoint){
  //build circle here.
 }

EDIT:

Where does _width and _height come from?

Those are arguments to constructors. You set values on them when you call the Constructor method.

In DrawFrame I set width and height. In DrawCircle I need to access the width and height of DrawFrame. How do I do this?

DrawFrame(){
   int width = 400;
   int height =400;

   /*
   * call DrawCircle constructor
   */
   content.pane(new DrawCircle(width,height));

   // other stuff

}

Now when the DrawCircle constructor executes, it will receive the values you used in DrawFrame as _width and _height respectively.

EDIT:

Try doing

 DrawFrame frame = new DrawFrame();//constructor contains code on previous edit.
 frame.setPreferredSize(new Dimension(400,400));

http://java.sun.com/docs/books/tutorial/uiswing/components/frame.html