Getting the value from class A-setting value from class A to B-and returning the value from class B to A

StackOverflow https://stackoverflow.com/questions/21831608

Question

I'm trying to learn this getting value - setting value - returning the value from where it came from style of coding. I heard this is kind of 'pass by value or reference' kind of problem, did my research and still stuck with the problem. Anyways, this is my source code:

System.out.println(x);
int x = object2.getX(); **//I HAVE A PROBLEM HERE** 
int x2 = rand.nextInt(100);
int y = rand.nextInt(100);
int xpost = rand.nextInt(300);
int ypost = rand.nextInt(150);
allField[x] = new JTextField(String.format("        %s + %s", x2 , y));
allField[x].setBounds(xpost, ypost, 100, 30);
allField[x].setEnabled(false);
add(allField[x]);
object2.setX(x++); **//I HAVE A PROBLEM HERE TOO**

I'm trying to get the value from another class through object2.getX(); from there it will set the indexes of the array. After done with the setting of array, which is still at 0, I want to increment it (x++) and that value, which is 1, is pass to another class and set it.

this is the other class:

public class TimerTutorial extends JFrame {
    JLabel promptLabel, timerLabel;
    int counter, x = 0;
    int changeTest;
    JTextField tf;
    JButton button;
    Timer timer;

    public int getX(){**//I HAVE A PROBLEM HERE**
        return x;
    }
    public int setX(int y){**//I HAVE A PROBLEM HERE**
        x = y;
        return this.x;
    }
}

If you want the whole code, but the problem is stated before this:

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

public class TimerTutorial extends JFrame{
    JLabel promptLabel, timerLabel;
    int counter, x = 0;
    int changeTest;
    JTextField tf;
    JButton button;
    Timer timer;

    public int getX(){
        return x;
    }
    public int setX(int y){
        x = y;
        return this.x;
    }


    public TimerTutorial(){
        setLayout(new GridLayout(2,2,5,5));

        tf = new JTextField();
        add(tf);

        promptLabel = new JLabel("Enter seconds:", SwingConstants.CENTER);
        add(promptLabel);

        button = new JButton("Start Timing");
        add(button);

        timerLabel = new JLabel("Waiting...", SwingConstants.CENTER);
        add(timerLabel);

        event e = new event();
        button.addActionListener(e);
    }
    public class event implements ActionListener{
        public void actionPerformed(ActionEvent e){
            int count = (int)(Double.parseDouble(tf.getText()));
            timerLabel.setText("Time left:" +count);

            TimeClass tc = new TimeClass(count);
            timer = new Timer(1000, tc);
            timer.start();
        }
    public class TimeClass implements ActionListener{
        int counter;

        public TimeClass(int counter){
            this.counter = counter;
        }

        public void actionPerformed(ActionEvent tc){//every time timer updates this will spark
            counter--;
            JTextField[] allField = new JTextField [20];
            TimerTutorial object2 = new TimerTutorial();
            Random rand = new Random();
            System.out.println(x);
            int x = object2.getX();
            int x2 = rand.nextInt(100);int y = rand.nextInt(100);
            int xpost = rand.nextInt(300); int ypost = rand.nextInt(150);
            allField[x] = new JTextField(String.format("        %s + %s", x2 , y));
            allField[x].setBounds(xpost, ypost, 100, 30);
            allField[x].setEnabled(false);
            add(allField[x]);
            object2.setX(x++);
            if(counter>=1) {
                timerLabel.setText("Time left: "+counter);
            } else {
                timer.stop();
                timerLabel.setText("Done!");
                Toolkit.getDefaultToolkit().beep();
            }
        }
    }
    }
    public static void main(String args[]){
        TimerTutorial gui = new TimerTutorial();
        gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        gui.setSize(800,800);
        gui.setVisible(true);
    }
}

The code is working fine actually. My aim is to just randomly post JTextFields in sec intervals with random position and values in it. The problem here is that the x does not increment. Which puts my JTextFields to index [0]. PS: still new to java, any tips will be appreciated

No correct solution

OTHER TIPS

Your problem is the confusion of classes and instances of classes. And, in addition, what it means to pass a value. YOu don't pass values to classes or instances, just to methods.

You have in you actionPerformed method this:

TimerTutorial object2 = new TimerTutorial();
...
int x = object2.getX();
...
object2.setX(x++);

(Left out code irrelevant for the problem marked with ...) The first creates a new (!) object TimerTutorial. The next gets some data from this new object, but because it is new and not changed inbetween, this will be the same value in every run of the actionPerformed method.

The last setX call is nonsensical, because the object2will be garbage collected shortly after, so it makes no sense to set a value. BTW, you set the same value as it had before.

Note: I do not explain post/pre increment/decrement operators. Just do not use them unless you 100% understand them!!!!

Never.

Ever.

Same goes for all other language constructs you don't understand yet.

Problem 1

Your first problem lies in your usage of the ++ operator:

object2.setX(x++);

What happens here is that the value of x is passed as a parameter to setX() and is incremented afterwards. Generally speaking x++ increments x but the the value of the statement is still the old x nontheless.

int x = 0;
System.out.println(x++); // 0
System.out.println(x);   // 1

You can avoid this by using ++x or x+1 instead.

Problem 2

Fixing the usage of the ++ operator won't help you much because you create a new TimerTutorial object each time you action listener method is executed.

public void actionPerformed(ActionEvent tc){
    ...
    TimerTutorial object2 = new TimerTutorial(); //new object is create which initializes it's instance variable x to 0
    ...
    int x = object2.getX(); //returns the instance variable x of object2 which is 0
    ...
    object2.setX(x++); //explained in problem 1
    //After here object2 is never used again in this method
    ...
} //at the end of the method, the scope of the variable object2 ends and the object it points to will be garbage collected

I hope now you can see that the x is 0 every time you execute your action listener gets executed. If you want to preserve your object and it's state in another scope, you'll have to declare that variable in that scope. In your case the action listener is already an inner class of TimerTutorial so you might not even need a new TimerTutorial object. You could just use the outer class. I'm still not sure what your program should achieve but I think that would be the way to go:

public void actionPerformed(ActionEvent tc){
    ...
    //TimerTutorial object2 = new TimerTutorial(); <= not needed
    ...
    int x = getX(); //returns the instance variable x of the outer class
    ...
    setX(x+1); //sets the instance variable x of the outer class
    ...
} //next time this method is called, the state of x will be preserved in the outer class
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top