Java: CardLayout переключение между картами

У меня есть класс «Рамка», который расширяет JFrame и разделяет JPanels: MainMenu и SinglePanel. Я использую CardLayout, но у меня проблема при переключении обратно на панели с помощью кнопок buttonSingle и powrot. Итак, мой вопрос: как я могу переключаться между картами с помощью этих кнопок?

Мой Frame класс:

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

мой MainMenu класс:

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

мой SinglePanel класс

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

Основной класс:

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

}

person TOM-12    schedule 23.03.2014    source источник
comment
docs.oracle.com/javase/tutorial/uiswing/layout/card. html   -  person JB Nizet    schedule 23.03.2014


Ответы (1)


Вам нужна ссылка на CardLayout из JFrame внутри ваших классов панелей. Что вы можете сделать, так это передать Frame в классы JPanel в качестве ссылки, затем вы можете использовать CardLayout из Frame в этих классах для show или next и т. д. Что-то вроде

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

Когда вы создаете MainPanel, вам нужно передать ему Frame.this, ссылаясь на текущий Frame

MainMenu menuPanel = new MainMenu(Frame.this);

ИЗМЕНИТЬ

Я только что заметил ваш метод swapView. Таким образом, вместо того, чтобы использовать CardLayout непосредственно в классе панели, вы можете просто вызвать swapView в классе actionPerformed.

frame.swapView("single");

Или еще лучше, чтобы не подвергать опасности класс Frame, вы можете реализовать в классе Frame interface скажем SwapInterface, у которого есть метод swapView, который вам нужно переопределить. И передайте SwapInterface классам панелей. Что-то типа

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

    }
}

Примечание

Как указал HovercraftFullOfEels в своем комментарии, вы должны использовать константы String для значений карт String, чтобы не было ошибок. Что-то типа

private static final String SINGLE_CARD = "single";

Затем в местах, где вы используете "single", используйте вместо этого SINGLE_CARD.

person Paul Samsotha    schedule 23.03.2014
comment
Я уже несколько раз видел этот метод использования интерфейса для переключения страниц. Это шаблон или у него есть название, чтобы я мог где-нибудь прочитать об этом подробнее? Потому что я не уверен, в каком порядке что используется, зачем мне нужен экземпляр (?) SwapInterface в классе MainMenu и т. д. - person hamena314; 07.06.2016