Este es obviamente el escenario en el que deberías estar usando CardLayout. Aquí, en lugar de abrir dos JFrame, lo único que puede hacer es cambiar los JPanels con CardLayout.
Y el código que se encarga de crear y mostrar su GUI debe estar dentro de SwingUtilities.invokeLater (...); método para que sea Thread Safe. Para obtener más información, debe leer sobre Concurrency in Swing.
Pero si quiere seguir con su enfoque, aquí hay un código de muestra para su ayuda.
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();
}
});
}
}
Y la salida será:
y
[¿El uso de múltiples JFrames, buenas/malas prácticas?] (Http://stackoverflow.com/questions/9554636/the-use-of-multiple-jframes- good-bad-practice-9554657#9554657) y [Eliminar contenedor de nivel superior en tiempo de ejecución] (http://stackoverflow.com/questions/6309407/remove-top-level-container-on-runtime) – mKorbel