[java] Java swing application, close one window and open another when button is clicked

I have a netbeans Java application that should display a JFrame (class StartUpWindow extends JFrame) with some options when the application is launched, then the user clicks a button and that JFrame should be closed and a new one (class MainWindow) should be opened.

So how do I do this correctly. I obviously set a click handler on the button in StartupWindow but what do I put in this handler so that I can close the StartUpWindow and open the MainWindow? It seems that threading comes into this too as every window seems to have their own thread...or are threading issues automatically handled by JFrames themselves...

This question is related to java swing

The answer is


You can call dispose() on the current window and setVisible(true) on the one you want to display.


You can hide a part of JFrame that contains the swing controls which you want on another JFrame.

When the user clicks on a Jbutton the JFrame width increases and when he clicks on another same kind of Jbutton the JFrame comes to the default size.

  JFrame myFrame = new JFrame("");
  JButton button1 = new JButton("Basic");
  JButton button2 = new JButton("More options");
 // actionPerformed block code for button1 (Default size)  
 myFrame.setSize(400, 400);
//  actionPerformed block code for button2 (Increase width)
 myFrame.setSize(600, 400);

        final File open = new File("PicDic.exe");
        if (open.exists() == true) {
            if (Desktop.isDesktopSupported()) {
                javax.swing.SwingUtilities.invokeLater(new Runnable() {

                    public void run() {
                        try {
                            Desktop.getDesktop().open(open);
                        } catch (IOException ex) {
                            return;
                        }
                    }
                });

                javax.swing.SwingUtilities.invokeLater(new Runnable() {

                    public void run() {
                        //DocumentEditorView.this.getFrame().dispose();
                        System.exit(0);
                    }

                });
            } else {
                JOptionPane.showMessageDialog(this.getFrame(), "Desktop is not support to open editor\n You should try manualy");
            }
        } else {
            JOptionPane.showMessageDialog(this.getFrame(), "PicDic.exe is not found");
        }

//you can start another apps by using it and can slit your whole project in many apps. it will work lot


Use this.dispose for current window to close and next_window.setVisible(true) to show next window behind button property ActionPerformed , Example is shown below in pic for your help.

enter image description here


This is obviously the scenario where you should be using CardLayout. Here instead of opening two JFrame, what you can do is simply change the JPanels using CardLayout.

And the code that is responsible for creating and displaying your GUI should be inside the SwingUtilities.invokeLater(...); method for it to be Thread Safe. For More Info you have to read about Concurrency in Swing.

But if you want to stick to your approach, here is a Sample Code for your Help.

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;

public class TwoFrames
{
    private JFrame frame1, frame2;
    private ActionListener action;
    private JButton showButton, hideButton;

    public void createAndDisplayGUI()
    {
        frame1 = new JFrame("FRAME 1");
        frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);      
        frame1.setLocationByPlatform(true);

        JPanel contentPane1 = new JPanel();
        contentPane1.setBackground(Color.BLUE);

        showButton = new JButton("OPEN FRAME 2");
        hideButton = new JButton("HIDE FRAME 2");

        action  = new ActionListener()
        {
            public void actionPerformed(ActionEvent ae)
            {
                JButton button = (JButton) ae.getSource();

                /*
                 * If this button is clicked, we will create a new JFrame,
                 * and hide the previous one.
                 */
                if (button == showButton)
                {
                    frame2 = new JFrame("FRAME 2");
                    frame2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);      
                    frame2.setLocationByPlatform(true);

                    JPanel contentPane2 = new JPanel();
                    contentPane2.setBackground(Color.DARK_GRAY);

                    contentPane2.add(hideButton);
                    frame2.getContentPane().add(contentPane2);
                    frame2.setSize(300, 300);
                    frame2.setVisible(true);
                    frame1.setVisible(false);
                }
                /*
                 * Here we will dispose the previous frame, 
                 * show the previous JFrame.
                 */
                else if (button == hideButton)
                {
                    frame1.setVisible(true);
                    frame2.setVisible(false);
                    frame2.dispose();
                }
            }
        };

        showButton.addActionListener(action);
        hideButton.addActionListener(action);

        contentPane1.add(showButton);

        frame1.getContentPane().add(contentPane1);
        frame1.setSize(300, 300);
        frame1.setVisible(true);
    }
    public static void main(String... args)
    {
        /*
         * Here we are Scheduling a JOB for Event Dispatcher
         * Thread. The code which is responsible for creating
         * and displaying our GUI or call to the method which 
         * is responsible for creating and displaying your GUI
         * goes into this SwingUtilities.invokeLater(...) thingy.
         */
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                new TwoFrames().createAndDisplayGUI();
            }
        });
    }
}

And the output will be :

Frame1 and Frame2


Call below method just after calling the method for opening new window, this will close the current window.

private void close(){
    WindowEvent windowEventClosing = new WindowEvent(this, WindowEvent.WINDOW_CLOSING);
    Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(windowEventClosing);
}

Also in properties of JFrame, make sure defaultCloseOperation is set as DISPOSE.