Button on FrameOne shall close FrameTwo. ActionListener referes object of another class in JAVA

坚强是说给别人听的谎言 提交于 2019-12-24 21:55:51

问题


I have two frames in separate classes (FrameOne and FrameTwo) FrameOne has two buttons. One to open FrameTwo and One shall close FrameTwo. How to open FrameTwo I know. But not how to close from Frame One. How do I code it to make it working? Thanks. (I know that there are similar questions. I red them all. But it didn't gave me the answer. Also GUI guides didn't helped.)

public class Main {

    public static void main(String[] args) {

        FrameOne frame = new FrameOne();
    }
}

FrameOne class:

    public class FrameOne extends JFrame implements ActionListener{

    private JButton btn1, btn2;

    FrameOne () {

        setVisible(true);
        setSize(400,400);
        setLayout(new FlowLayout());
        setTitle("Main");
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        btn1 = new JButton("opens FrameTwo");
        btn2 = new JButton("close FrameTwo");
        btn1.addActionListener(this);
        btn2.addActionListener(this);
        add(btn1);
        add(btn2);
    }

    @Override
    public void actionPerformed (ActionEvent e) {
        if(e.getSource()== btn1) {  
            FrameTow frameTwo = new FrameTwo(); 
        }

        else if(e.getSource()== btn2) ;
        // {???.dispose(); }
    }
}

` Frame2 class:

    public class FrameTow extends JFrame {

    FrameTwo () {

        setVisible(true);
        setSize(400,400);
        setTitle("FrameTwo");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        this.setLocation(400, 400);

    }
}

回答1:


Any of the below solutions will work

frameTwo.dispatchEvent(new WindowEvent(frameTwo, WindowEvent.WINDOW_CLOSING));

OR

frameTwo.setVisible(false);



回答2:


public class FrameOne extends JFrame implements ActionListener{

    private JButton btn1, btn2;
    private Window frameTwo = null; // <---- here is all I could do. I don't know how to go on

    FrameOne () {

        setVisible(true);
        setSize(400,400);
        setLayout(new FlowLayout());
        setTitle("Main");
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        btn1 = new JButton("opens FrameTwo");
        btn2 = new JButton("close FrameTwo");
        btn1.addActionListener(this);
        btn2.addActionListener(this);
        add(btn1);
        add(btn2);
    }

    @Override
    public void actionPerformed (ActionEvent e) {
        if(e.getSource()== btn1)    {
            FrameTwo frameTwo = new FrameTwo();
        }

        else if(e.getSource()== btn2) {

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



回答3:


The short answer is modify FrameOne :

private JFrame frameTwo; //introduce a field  


@Override
public void actionPerformed (ActionEvent e) {
    if(e.getSource()== btn1) {
        frameTwo = new FrameTwo();  //use field in action listener 
    }

    else if(e.getSource()== btn2){
        frameTwo.dispose();         //use field in action listener 
    }
}

The longer answer: using a JDialog for the 2nd frame is a better practice:

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;

public class Main {

    public static void main(String[] args) {

       new FrameOne();
    }
}

class FrameOne extends JFrame implements ActionListener{

    private final JButton btn1, btn2;
    private JDialog frameTwo; //introduce a field

    FrameOne () {

        setSize(400,400);
        setLayout(new FlowLayout());
        setTitle("Main");
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        btn1 = new JButton("opens FrameTwo");
        btn2 = new JButton("close FrameTwo");
        btn1.addActionListener(this);
        btn2.addActionListener(this);
        add(btn1);
        add(btn2);
        setVisible(true); //make it visible after construction is completed
    }

    @Override
    public void actionPerformed (ActionEvent e) {
        if(e.getSource()== btn1) {
            frameTwo = new FrameTwo();  //use field in action listener
        }

        else if(e.getSource()== btn2){
            frameTwo.dispose();         //use field in action listener
        }
    }
}

class FrameTwo extends JDialog {

    FrameTwo() {

        setSize(400,400);
        setTitle("FrameTwo");
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        this.setLocation(400, 400);
        setVisible(true); //make it visible after construction is completed
    }
}



回答4:


This is what the code looks now. But it is that FrameTwo is not closing by pressing the button at FrameOne

public class Main {

public static void main(String[] args) {

FrameOne frameOne = new FrameOne ();

}}

.

public class FrameOne extends JFrame implements ActionListener {

private JButton btnOpen;
private JButton btnClose;
private FrameTwo frameTwo = null;

FrameOne(){


    setButtons();
    setActions();

    setSize(400,400);
    setLocation(300, 250);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    setLayout(new FlowLayout());
    setVisible(true);

}




private void setButtons(){

    btnOpen = new JButton("Open");
    btnClose = new JButton("Close");
    add(btnOpen);
    add(btnClose);

}



private void setActions() { 

    btnOpen.addActionListener(this);
    btnClose.addActionListener(this);
}



@Override
public void actionPerformed(ActionEvent e) {

    if(e.getSource() == btnOpen) {
        if(frameTwo == null) {
        frameTwo = new FrameTwo();
    }

    else if(e.getSource() == btnClose) {
    frameTwo.dispatchEvent(new WindowEvent(frameTwo,WindowEvent.WINDOW_CLOSING));
    frameTwo = null;

    }
}}}

.

public class FrameTwo extends JDialog {

FrameTwo() {

setSize(400,400);
setLocation(900, 250);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setVisible(true);

}}



回答5:


In the example you show, one can open several instances of FrameTwo. Which one should the second button close?

Assuming you want there to be only one, you could introduce a field in in FrameOne, initially set to null. btn1 would then only open a frame if the field is null, and assign it to the field. Then btn2 can call dispose() on the field (and reset it to null).

Example, based on your attempt:

public class FrameOne extends JFrame implements ActionListener {

private JButton btn1, btn2;
private FrameTwo frameTwo = null;

FrameOne () {

setVisible(true);
setSize(400,400);
setLayout(new FlowLayout());
setTitle("Main");
setDefaultCloseOperation(EXIT_ON_CLOSE);

btn1 = new JButton("opens FrameTwo");
btn2 = new JButton("close FrameTwo");
btn1.addActionListener(this);
btn2.addActionListener(this);
add(btn1);
add(btn2);



}

@Override
public void actionPerformed (ActionEvent e)
{if(e.getSource()== btn1) 
{
    if (frameTwo == null) {    
        frameTwo = new FrameTwo();
    }
}

else if(e.getSource()== btn2) {

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

}}}


来源:https://stackoverflow.com/questions/59322886/button-on-frameone-shall-close-frametwo-actionlistener-referes-object-of-anothe

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!