G S
G S

Reputation: 7

How can I get the value out of a run method?

I have two frames. The first has a button. By clicking it a second frame is opened and a timer starts. The second frame can be closed by pressing the button again or by waiting until the timer has incremented a local variable x to three. I had several approaches.

  1. The button started only the timer and within the run method of the timer, the second frame was opened. When the timer incremented the variable x to three the second frame closed. It worked properly. The problem was that I wasn't able to close the frame by pressing the button again. So I tried the following.

  2. The button opens the second frame and the second frame contains an object of the timer. Now I can close the second frame by clicking on the button again. But it won't close when the timer has incremented x to three because the second frame is now out of the run method and has no more access to the local variable x.

And here is my problem. I just don't know how to get the value of x out of the run method. The run method allows no parameters to pass the value. To access it with timerClass.x doesn't change anything. Here the code.

public class Main {

public static void main(String[] args) {

    FrameOne frameOne = new FrameOne ();
}}

.

///////////////////////////////////////     THE FIRST FRAME 

public class FrameOne extends JFrame implements ActionListener {

private FrameTwo frameTwo;
private JButton btn= new JButton();

///////////////////////    PROPERTIES OF THE FIRST FRAME

FrameOne(){

    btn.addActionListener(this);
    add(btn);
    setSize(400,400);
    setLocation(300, 250);
    setLayout(new FlowLayout());
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    setVisible(true);
}


///////////////////////     OPENS THE SECOND FRAME BY CLICKING THE BUTTON

public void actionPerformed(ActionEvent e) {                

    if (e.getSource() == btn && frameTwo == null) {

            frameTwo = new FrameTwo();  
}


///////////////////////     CLOSES THE SECOND FRAME BY CLICKING THE BUTTON AGAIN


    else if (e.getSource() == btn && frameTwo != null) {  

            frameTwo.dispatchEvent(new WindowEvent(frameTwo, WindowEvent.WINDOW_CLOSING));
            frameTwo = null;
    }}

}

.

///////////////////////////////////////     THE SECOND FRAME


public class FrameTwo extends JDialog {

TimerClass timerClass;

FrameTwo() {


    setSize(400,400);
    setLocation(900, 250);
    setDefaultCloseOperation(DISPOSE_ON_CLOSE);
    setVisible(true);
    timerClass = new TimerClass();  // starts the timer


//////////////////////////     HERE I TRY TO LET THE TIMER CLOSE THE FRAME AT 3    ////////

    if(timerClass.x == 3) {this.dispatchEvent(
        new WindowEvent(
            this, WindowEvent.WINDOW_CLOSING));
               }}}

.

//////////////////       THE TIMER       
//////////////////       IT INCREMENTS x
//////////////////       WHEN x = 3 IT SHALL CLOSE THE FRAME 


public class TimerClass implements EventListener{

            public Timer timer = new Timer(true);
            public int x;

    TimerClass(){

        timer.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                x++;
        }

    },0,1000);
}}

I was also recommended to use frameTwo.dispose(); instead of the this.dispatchEvent command. Or use frameTwo.dispatchEvent and so on. Nothing ever worked. I know that it is because I am not familiar enough with passing values of variables. Please don't give me a hind to use tutorials. I need to know it from this example to make quick progress. It is my way of learning. Thank you for your sympathy and your efforts.

Upvotes: 0

Views: 55

Answers (1)

SteffenJacobs
SteffenJacobs

Reputation: 412

A simple fix would be to move the timerClass.x == 3 check into the timer class as such:

In class FrameTwo replace:

timerClass = new TimerClass();  // starts the timer

with

timerClass = new TimerClass(()->this.dispatchEvent(new WindowEvent(this, WindowEvent.WINDOW_CLOSING)));

In class TimerClass replace the constructor:

TimerClass(){

        timer.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                x++;
        }

    },0,1000);

with

TimerClass(Runnable runWhenThree) {    
            timer.scheduleAtFixedRate(new TimerTask() {
                @Override
                public void run() {
                    x++;
                    if(x == 3) {
                        runWhenThree.run();
                    }                       
                }    
            }, 0, 1000);
        }

Upvotes: 1

Related Questions