[java] 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?

This question is related to java variables

The answer is


Java inbuilt libraries support only AIFC, AIFF, AU, SND and WAVE formats. Here I only discussed playing an audio file using Clip only and see the various methods of a clip.

  1. Create a main class PlayAudio.java.
  2. Create helper class Audio.java.

PlayAudio.java

import java.io.IOException;
import java.util.Scanner;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
public class PlayAudio {
public static void main(String[] args) throws 
UnsupportedAudioFileException, IOException, 
LineUnavailableException {

    PlayMp3 playMp3;
    playMp3=new PlayMp3();


    Scanner sc = new Scanner(System.in);

    while (true) {
        System.out.println("Enter Choice :-");
        System.out.println("1. Play");
        System.out.println("2. pause");
        System.out.println("3. resume");
        System.out.println("4. restart");
        System.out.println("5. stop");

        System.out.println(PlayMp3.status);
        System.out.println(":::- ");
        int c = sc.nextInt();

        if (c ==5){

            playMp3.stop();
            break;
        }

        switch (c) {
            case 1:
                playMp3.play();
                break;
            case 2:
                playMp3.pause();
                break;
            case 3:
                playMp3.resume();
                break;
            case 4:
                playMp3.restart();
                break;
            case 5:
                playMp3.stop();
            default:
                System.out.println("Please Enter Valid Option :-");

        }
    }
    sc.close();
   }
}

Audio.java

import javax.sound.sampled.*;
import java.io.File;
import java.io.IOException;

public class Audio {

private String filePath="mp.snd";
public static String status="paused";
private Long currentFrame=0L;
private Clip clip;

private AudioInputStream audioInputStream;

public Audio() throws UnsupportedAudioFileException, IOException, LineUnavailableException {

    audioInputStream = AudioSystem.getAudioInputStream(new File(filePath));

    clip = AudioSystem.getClip();

    clip.open(audioInputStream);

}


public void play(){
    clip.start();
    status = "playing";
}

public void pause(){

    if (status.equals("paused")) {
        System.out.println("audio is already paused");
        return;
    }
    currentFrame = clip.getMicrosecondPosition();
    clip.stop();
    status = "paused";
}
public void resume() throws UnsupportedAudioFileException, IOException, LineUnavailableException {
    if (status.equals("play"))
    {
        System.out.println("Audio is already being playing");
        return;
    }
    clip.close();

    //starts again and goes to currentFrame
    resetAudioStream();
    clip.setMicrosecondPosition(currentFrame);
    play();
    status="playing";

}

public void restart() throws UnsupportedAudioFileException, IOException, LineUnavailableException {
    clip.stop();
    clip.close();
    resetAudioStream();
    currentFrame = 0L;
    clip.setMicrosecondPosition(0);
    play();
    status="Playing from start";
}

public void stop(){

    currentFrame = 0L;
    clip.stop();
    clip.close();
    status="stopped";
}

private void resetAudioStream() throws IOException, UnsupportedAudioFileException, LineUnavailableException {

    audioInputStream = AudioSystem.getAudioInputStream(new File(filePath).getAbsoluteFile());
    clip.open(audioInputStream);

   }

}

if what you need is the width and height of the frame in the circle, why not pass the DrawFrame width and height into the DrawCircle constructor:

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

you could also add a couple new methods to DrawCircle:

public void setWidth(int w) 
   this.w = w;

public void setHeight(int h)
   this.h = h; 

or even:

public void setDimension(Dimension d) {
   w=d.width;
   h=d.height;
}

if you go down this route, you will need to update DrawFrame to make a local var of the DrawCircle on which to call these methods.

edit:

when changing the DrawCircle constructor as described at the top of my post, dont forget to add the width and height to the call to the constructor in DrawFrame:

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();
    //pass in the width and height to the DrawCircle contstructor
    contentPane.add(new DrawCircle(width, height));
 }
}

I hope I'm understanding the problem correctly, but it looks like you don't have a reference back to your DrawFrame object from DrawCircle.

Try this:

Change your constructor signature for DrawCircle to take in a DrawFrame object. Within the constructor, set the class variable "d" to the DrawFrame object you just took in. Now add the getWidth/getHeight methods to DrawFrame as mentioned in previous answers. See if that allows you to get what you're looking for.

Your DrawCircle constructor should be changed to something like:

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

The last line of code in DrawFrame should look something like:

contentPane.add(new DrawCircle(this));

Then, try using d.getheight(), d.getWidth() and so on within DrawCircle. This assumes you still have those methods available on DrawFrame to access them, of course.


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


Filename=url.java

public class url {

    public static final String BASEURL = "http://192.168.1.122/";

}

if u want to call the variable just use this:

url.BASEURL + "your code here";


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.


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.