4

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);
    }
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
lecardo
  • 1,208
  • 4
  • 15
  • 37

2 Answers2

4

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");
           }
       }
   }
}
M A
  • 71,713
  • 13
  • 134
  • 174
3

If you want to simulate someone pressing the [X] button then you can use this code to programmatically trigger this event:

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

Aside from that, your code is not working because you are not closing your instance of the small window, instead you are creating another instance and disposing of it. Inside your close event you should be closing the smallFrame instance.

You can do this by either passing your JFrame to the constructor of your ActionListener or making smallFrame a class variable.

It appears you are using the small JFrame as a pop up to get information or display information. If so, you may want to look into the JOptionPane class which is made for "Dialogue Boxes".

Documentation:

http://docs.oracle.com/javase/7/docs/api/javax/swing/JOptionPane.html

chrissukhram
  • 2,957
  • 1
  • 13
  • 13
  • Yeap I looked into option pane but prefer to use the JFrame instead. – lecardo Mar 24 '15 at 17:46
  • Ah I see, although that is not the best practice, if it is what you want then in that case closing the window using the code above would be your best bet. Be sure that you are closing the instance of the window that triggered it and not creating a new one and closing it as your commented code does. – chrissukhram Mar 24 '15 at 17:58
  • Yeap thanks! i did have a look at your idea but it closed a bit too much for what needed to be done. Thanks anyways....i still rated your question up for future references for anyone – lecardo Mar 24 '15 at 18:47
  • Closed a bit too much? Do you want to preserve the frame but just make it invisible so you don't have to re-instantiate it? In that case you can just `setVisible(false)` – chrissukhram Mar 24 '15 at 19:57