Question

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();
    }

}
Was it helpful?

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top