Reputation: 7
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.
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.
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
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