Riley Head
Riley Head

Reputation: 25

Using ActionListener with JMenuBar and CardLayout

I'm testing out a basic java swing GUI setup with a navigation bar and a cardlayout. I'm trying to get the items in the JMenuBar to change what card is shown on the page. I've successfully created the navigation bar and the three cards. I've also added an actionlistener to detect when an item in the JMenuBar is pressed and then eventually change the card. Currently, when trying to retrieve the layout in the actionlistener i receive the error, Cannot Invoke "java.swing.JPanel.getLayout()" because "this.cards" is null. Code is pasted below. Thanks

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

public class testgui extends JFrame implements  Runnable, ActionListener {
    JPanel cards; //a panel that uses CardLayout
    final static String BUTTONPANEL = "Card 1";
    final static String TEXTPANEL = "Card 2";
    final static String CARD3 = "Card 3";

    JMenu cardList;
    JMenuItem card1, card2, card3;

    public testgui(String title) {
        super(title);
    }

    private JPanel card1(){
        JPanel card1 = new JPanel();
        card1.add(new JButton("Button 1"));
        card1.add(new JButton("Button 2"));
        card1.add(new JButton("Button 3"));

        return  card1;
    }

    private JPanel card2(){
        JPanel card2 = new JPanel();
        card2.add(new JTextField("TextField", 20));

        return card2;
    }

    private JPanel card3(){
        JPanel card3 = new JPanel();
        JLabel label = new JLabel("Card 3");
        card3.add(label);

        return card3;
    }

    private JMenuBar navbar(){
        JMenuBar navbar = new JMenuBar();

        card1 = new JMenuItem("Card 1");
        card2 = new JMenuItem("Card 2");
        card3 = new JMenuItem("Card 3");

        card1.addActionListener(this);
        card2.addActionListener(this);
        card3.addActionListener(this);

        cardList = new JMenu("Cards");
        cardList.add(card1);
        cardList.add(card2);
        cardList.add(card3);

        navbar.add(cardList);

        return navbar;
    }

    public void addComponentToPane(Container pane) {

        //Cards are created using separate methods

        //Create the panel that contains the "cards".
        cards = new JPanel(new CardLayout());
        cards.add(card1(), BUTTONPANEL);
        cards.add(card2(), TEXTPANEL);
        cards.add(card3(), CARD3);

        setVisible(true);

        //Everything is added to a pane.
//        pane.add(comboBoxPane, BorderLayout.PAGE_START);
        pane.add(cards, BorderLayout.CENTER);
    }


    public void actionPerformed(ActionEvent e){
        CardLayout layout = (CardLayout) cards.getLayout();
        //Why is the above line giving me the error saying that this.cards is null?
    }


    /**
     * Create the GUI and show it.  For thread safety,
     * this method should be invoked from the
     * event dispatch thread.
     */
    private void createAndShowGUI() {
        //Create and set up the window.
        JFrame frame = new JFrame("CardLayoutDemo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //Create the navbar

        //Create and set up the content pane.
        testgui demo = new testgui("hello");
        demo.addComponentToPane(frame.getContentPane());

        //Display the window.
        frame.setJMenuBar(navbar());
        frame.pack();
        frame.setVisible(true);
    }


    public static void main(String[] args) {
        SwingUtilities.invokeLater(new testgui("test gui"));
    }

    public void run() {
        setSize(700, 500);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        createAndShowGUI();
    }


}

Upvotes: 1

Views: 81

Answers (1)

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285403

You're problem is here:

    testgui demo = new testgui("hello");
    demo.addComponentToPane(frame.getContentPane());

You're creating one too many JFrame/GUI unnecessarily, setting the JPanel on one and displaying the other (the one with the still null JPanel). The solution is to not do this, to change the above lines to:

    // testgui demo = new testgui("hello");
    this.addComponentToPane(frame.getContentPane());

or more simply:

addComponentToPane(frame.getContentPane());

Upvotes: 1

Related Questions