0

I've been looking around, including in the Java documentation, but there isn't a clear answer that I've found for my question : I would like to switch from one JFrame to another at the click of a button; that is, have the old JFrame close while the new one opens. I've heard of "CardLayout" but I'm not so sure how it works. Would anyone mind explaining it, or some other method?

Thanks

3.14ed_Piper
  • 151
  • 2
  • 10
  • 2
    Short answer is, don't (switch frames) - See [The Use of Multiple JFrames, Good/Bad Practice?](http://stackoverflow.com/q/9554636/418556) for more of a discussion. A `CardLayout` would generally be a more suitable solution for switching between multiple views within your UI, but rely on basic components (like `JPanel`) rather than frames. You should, as a general rule of thumb, avoid extending directly from `JFrame`, instead preferring the use of other containers, like `JPanel`, which can be added to whatever container you need with whatever layout you want – MadProgrammer Jan 26 '16 at 00:14

2 Answers2

3

Here is an example of a CardLayout

As you've heard other say, don't use multiple JFrames.

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

public class MainFrame
{
static JPanel homeContainer;
static JPanel homePanel;
static JPanel otherPanel;
static CardLayout cl;

public MainFrame()
{
    JFrame mFrame = new JFrame("CardLayout Example");
    JButton showOtherPanelBtn = new JButton("Show Other Panel");
    JButton backToHomeBtn = new JButton("Show Home Panel");

    cl = new CardLayout(5, 5);
    homeContainer = new JPanel(cl);
    homeContainer.setBackground(Color.black);

    homePanel = new JPanel();
    homePanel.setBackground(Color.blue);
    homePanel.add(showOtherPanelBtn);

    homeContainer.add(homePanel, "Home");

    otherPanel = new JPanel();
    otherPanel.setBackground(Color.green);
    otherPanel.add(backToHomeBtn);

    homeContainer.add(otherPanel, "Other Panel");

    showOtherPanelBtn.addActionListener(e -> cl.show(homeContainer, "Other Panel"));
    backToHomeBtn.addActionListener(e -> cl.show(homeContainer, "Home"));

    mFrame.add(homeContainer);
    cl.show(homeContainer, "Home");
    mFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    mFrame.setLocationRelativeTo(null);
    mFrame.setExtendedState(JFrame.MAXIMIZED_BOTH);
    mFrame.pack();
    mFrame.setVisible(true);
}

public static void main(String[] args)
{
    SwingUtilities.invokeLater(MainFrame::new);
}
}
Community
  • 1
  • 1
Jonah
  • 1,013
  • 15
  • 25
0

You don't need to use a CardLayout for anything in this case. In fact, JFrame's don't have layouts.

Here's some code to illustrate that idea (assuming you're using Java 8; otherwise, add the final modifier to oldFrame and newFrame:

JFrame parent = new JFrame();

JDialog oldFrame = new JDialog("My Old Frame's Title");
JDialog newFrame = new JDialog("My New Frame's Title");

JPanel panel = new JPanel();
JButton myButton = new JButton();

myButton.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        oldFrame.dispose(); //closes your old frame
        newFrame.setVisible(true); //opens your new frame
    }
});

panel.add(myButton);
oldFrame.add(panek);
oldFrame.setVisible(true);

Whenever you click your button, the old frame closes, and the new one opens.

Lucas Baizer
  • 305
  • 2
  • 5
  • 13
  • [The Use of Multiple JFrames, Good/Bad Practice?](http://stackoverflow.com/q/9554636/418556) - As a general rule of thumb, a `CardLayout` would be a preferrable solution for displaying multiple views then switching frames – MadProgrammer Jan 26 '16 at 00:04
  • @MadProgrammer `JFrame`s don't have layouts. Or at least it's bad practice to directly add components to `JFrame`s, thus removing the need for any layouts to be added. – Lucas Baizer Jan 26 '16 at 00:04
  • 4
    Well, that's just WRONG. Of course `JFrame`s have layouts. `JFame` extends from `Frame`, which extends from `Window` which extends from `Container`, which defines the [`setLayout`](https://docs.oracle.com/javase/7/docs/api/java/awt/Container.html#setLayout(java.awt.LayoutManager)). `JFrame` overrides `setLayout` so that the call is forwarded to the `contentPane`, but the principle still applies. The default layout for `JFrame` is `BorderLayout`, which you can change to whatever you want, but I'd discourage extending directly from `JFrame` anyway and start by using `JPanel` for the base UI – MadProgrammer Jan 26 '16 at 00:06
  • @MadProgrammer I agree on that. – Lucas Baizer Jan 26 '16 at 00:10
  • 1
    *"Or at least it's bad practice to directly add components to JFrames"* - but that's precisely what you're encouraging the OP to do. The OP should have a single instance of `JFrame` which acts as the container for something like `JPanel`, onto which the core UI is built on (using a `CardLayout` to allow them to switch between views) – MadProgrammer Jan 26 '16 at 00:11
  • Besides, if you have a complex enough UI (multiple views spread across multiple panels), there's nothing wrong with using a `JFrame` with a `CardLayout` to manage it – MadProgrammer Jan 26 '16 at 00:13
  • So I'm editing code in Netbeans, how might I "access" CardLayout from a Drag+Drop style IDE? – 3.14ed_Piper Jan 26 '16 at 00:19
  • 2
    @3.14ed_Piper: You shouldn't use drag and drop. Until you completely understand how [Swing Layouts](https://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html) work, you should code your Swing GUI yourself. – Gilbert Le Blanc Jan 26 '16 at 00:38