Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swing - Dispose a frame [duplicate]

Tags:

java

swing

jframe

My aim is for an action listener to close a specific JFrame when the user hits the JButton to quit.

Overall, when the program starts a large JFrame opens then a small one in front....in my code the user enters some details in this small one and hits submit(for the sake of simplicity, ive omitted this code here and replaced submit with quit)

So when this quit buttons pressed. I expect this small JFrame to close. I can't seem to figure this out. The action listeners in a different class and ive tried making instances and had no luck. I've commented out the code I've tried below when attempting to solve this issue.

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

public class test
{
    public static void main(String Args[])
    {
    makeGUI m = new makeGUI();
    }
}

class makeGUI
{
    JButton close = new JButton("CLOSE ME");

    makeGUI()
    {
    frame f1 = new frame();

    JFrame smallframe = new JFrame(); //want to close this one
    JPanel jp = new JPanel(new FlowLayout());
    smallframe.setSize(300,300);
    smallframe.setLocationRelativeTo(null);
    smallframe.setDefaultCloseOperation(smallframe.DISPOSE_ON_CLOSE);
    close.addActionListener(new action());
    jp.add(close);
    smallframe.add(jp);
    smallframe.setVisible(true);
    }

    class action implements ActionListener
    {
    public void actionPerformed(ActionEvent e)
    {
        //makeGUI s1 = new makeGUI();
        if (e.getSource () == close)
        {
            //s1.smallframe.dispose();
            System.out.println("gotcha");
        }
    }
    }    
}

class frame extends JFrame
{
    frame ()
    {
    setExtendedState(JFrame.MAXIMIZED_BOTH);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setTitle("big one");
    setVisible(true);
    }
}
like image 544
lecardo Avatar asked Mar 16 '23 15:03

lecardo


1 Answers

First, it's not a good practice to name classes with a lowercase, so try renaming to something like MakeGUI instead of makeGUI.

The problem with your commented code is that it creates a new instance of makeGUI every time the button is clicked and the action listener is invoked. The result is that when you click on the close button, a new frame is created, then an inner one and this inner one gets immediately closed. The only thing you'd be doing is creating more and more frames. You should keep the instance as a state, for instance as a class member:

class MakeGUI {
   JFrame smallframe;
   JButton close = new JButton("CLOSE ME");


   MakeGUI() {
       frame f1 = new frame();
       smallframe = new JFrame(); //want to close this one
       JPanel jp = new JPanel(new FlowLayout());
       smallframe.setSize(300, 300);
       smallframe.setLocationRelativeTo(null);
       smallframe.setDefaultCloseOperation(smallframe.DISPOSE_ON_CLOSE);
       close.addActionListener(new action());
       jp.add(close);
       smallframe.add(jp);
       smallframe.setVisible(true);
   }

   class action implements ActionListener {
       public void actionPerformed(ActionEvent e) {
           if (e.getSource() == close) {
               // use this instead of dispose
               smallframe.dispatchEvent(new WindowEvent(smallframe, WindowEvent.WINDOW_CLOSING));
               System.out.println("gotcha");
           }
       }
   }
}
like image 97
M A Avatar answered Mar 27 '23 12:03

M A