16

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...

Jim_CS
  • 4,082
  • 13
  • 44
  • 80
  • 3
    [The Use of Multiple JFrames, Good/Bad Practice?](http://stackoverflow.com/questions/9554636/the-use-of-multiple-jframes-good-bad-practice/9554657#9554657) and [Remove Top-Level Container on Runtime](http://stackoverflow.com/questions/6309407/remove-top-level-container-on-runtime) – mKorbel Mar 05 '12 at 23:01

7 Answers7

27

Here is an example:

enter image description here

enter image description here

StartupWindow.java

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


public class StartupWindow extends JFrame implements ActionListener
{
    private JButton btn;

    public StartupWindow()
    {
        super("Simple GUI");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        btn = new JButton("Open the other JFrame!");
        btn.addActionListener(this);
        btn.setActionCommand("Open");
        add(btn);
        pack();

    }

    @Override
    public void actionPerformed(ActionEvent e)
    {
        String cmd = e.getActionCommand();

        if(cmd.equals("Open"))
        {
            dispose();
            new AnotherJFrame();
        }
    }

    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable(){

            @Override
            public void run()
            {
                new StartupWindow().setVisible(true);
            }

        });
    }
}

AnotherJFrame.java

import javax.swing.JFrame;
import javax.swing.JLabel;

public class AnotherJFrame extends JFrame
{
    public AnotherJFrame()
    {
        super("Another GUI");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        add(new JLabel("Empty JFrame"));
        pack();
        setVisible(true);
    }
}
Eng.Fouad
  • 115,165
  • 71
  • 313
  • 417
10

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

nIcE cOw
  • 24,468
  • 7
  • 50
  • 143
  • 1
    So we meet again ... another great example +1 . – JAN Aug 10 '13 at 15:40
  • 1
    @ron : This [example](http://stackoverflow.com/a/9443609/1057230), does not allow a user to open more than one `JFrame`, this checks for the condition too, if a `JFrame` is open, then not to open a new one. – nIcE cOw Aug 10 '13 at 16:32
8

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

Garrett Hall
  • 29,524
  • 10
  • 61
  • 76
  • Would you keep the JFrame variable in class scope? or you would make it selectable for garbage collection once the second JFrame is displayed? – Timoteo Ponce Mar 05 '12 at 19:53
  • dispose() will make it garbage collectable so long as you don't hold any other references to it. – Garrett Hall Mar 05 '12 at 20:07
1
        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

0

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

0

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.

Danger
  • 433
  • 5
  • 17
0

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);
User9211
  • 194
  • 1
  • 2
  • 17