问题
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