Java: CardLayout switching between cards

cardlayout, java, swing

Solution

You need a reference to the `CardLayout` of the `JFrame` inside your panel classes. What you can do is pass the `Frame` to the `JPanel` classes as reference, then you can use the `CardLayout` of the `Frame` in those classes to `show` or `next` etc. Something like

public class MainMenu {
    private CardLayout layout;
    private Frame frame;

    public MainMenu(final Frame frame) {
         this.frame = frame;
         this.layout = (CardLayout)frame.getLayout();

         JButton buttonSingle = new JButton("Single");     
         buttonSingle.setAlignmentX(Component.CENTER_ALIGNMENT);
         buttonSingle.addActionListener(new ActionListener(){
             @Override
             public void actionPerformed(ActionEvent e) {
                 layout.show(frame, "single");
             }
         });
    }
}

When you create the `MainPanel`, you need to pass `Frame.this` to it, referencing the current `Frame`

MainMenu menuPanel = new MainMenu(Frame.this);

EDIT

I just noticed your `swapView` method. So instead of use the `CardLayout` directly in the panel class, you can actually just call `swapView` in the `actionPerformed`

frame.swapView("single");

Or better yet, as to not expose the `Frame` class, you can have the `Frame` class implement an `interface` say `SwapInterface` that has a method `swapView` you need to override. And pass the `SwapInterface` to the panel classes. Something like

public interface SwapInterface {
    public void swapView(String view);
}

public Frame extends JFrame implements SwapInterface {
    MainMenu mainPanel = new MainMenu(Frame.this);
    ....
    @Override
    public void swapView(String view) {
        cl.show(getContentPane(), view);
    }
}

public class MainMenu extends JPanel {
    private SwapInterface swap;

    public MainMenu(SwapInterface swap) {
        this.swap = swap;
        ...
        public void actionPerfomed(ActionEvent e) {
            swap.swapView("single");
        }

    }
}

Side Note

As HovercraftFullOfEels pointed out in his comment, you should make use of String contants for the String card values so there's no mistakes. Something like

private static final String SINGLE_CARD = "single";

Then in places where you use `"single"`, use `SINGLE_CARD` instead

Problem

I've got class 'Frame' which extends `JFrame` and separetad `JPanels`: `MainMenu` and `SinglePanel` I am using `CardLayout`, but I've got problem when switching back to panels using `buttonSingle` and `powrot` buttons. So my question is how can I change/swap between cards using these buttons? My `Frame` class: ``` public class Frame extends JFrame{ CardLayout cl = new CardLayout(); final MainMenu menuPanel = new MainMenu(); final SinglePanel singlePanel = new SinglePanel(); public Frame(){ setLayout(cl); add(menuPanel,"menu"); add(singlePanel,"single"); setSize(200, 200); setLocationRelativeTo(null); setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); setVisible(true); setEnabled(true); swapView("menu"); } public void swapView(String view){ cl.show(getContentPane(),view); } } ``` my `MainMenu` class: ``` public class MainMenu extends JPanel{ public MainMenu(){ setLayout(new BoxLayout(this , BoxLayout.Y_AXIS)); add(Box.createVerticalGlue()); JButton buttonSingle = new JButton("Single"); buttonSingle.setAlignmentX(Component.CENTER_ALIGNMENT); buttonSingle.addActionListener(new ActionListener(){ @Override public void actionPerformed(ActionEvent e) { } }); add(buttonSingle); add(Box.createVerticalGlue()); JButton buttonMulti = new JButton("Multiplayer"); buttonMulti.setAlignmentX(Component.CENTER_ALIGNMENT); buttonMulti.addActionListener(new ActionListener(){ @Override public void actionPerformed(ActionEvent e) { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } }); add(buttonMulti); add(Box.createVerticalGlue()); JButton buttonExit = new JButton("Wyjście"); buttonExit.setAlignmentX(Component.CENTER_ALIGNMENT); buttonExit.addActionListener(new ActionListener(){ @Override public void actionPerformed(ActionEvent e) { System.exit(0); }}); add(buttonExit); add(Box.createVerticalGlue()); } } ``` my `SinglePanel` class ``` public class SinglePanel extends JPanel{ SinglePanel(){ setLayout(new FlowLayout()); JButton powrot = new JButton("Wróć do menu"); powrot.addActionListener(new ActionListener(){ @Override public void actionPerformed(ActionEvent e) { } }); add(powrot); } } ``` Main class: ``` public class Main { /** * @param args the command line arguments */ public static void main(String[] args) { // TODO code application logic here /*MainMenu mM = new MainMenu();*/ Frame f = new Frame(); } } ```

Original source