将 ActionListener 与 JMenuBar 和 CardLayout 一起使用

Using ActionListener with JMenuBar and CardLayout

我正在测试带有导航栏和卡片布局的基本 java swing GUI 设置。我正在尝试获取 JMenuBar 中的项目以更改页面上显示的卡片。我已经成功创建了导航栏和三张卡片。我还添加了一个动作侦听器来检测何时按下 JMenuBar 中的项目,然后最终更改卡片。目前,当尝试在 actionlistener 中检索布局时,我收到错误消息,无法调用“java.swing.JPanel.getLayout()”,因为“this.cards”为空 。代码贴在下面。谢谢

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


}

你的问题在这里:

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

您不必要地创建了太多 JFrame/GUI,将 JPanel 设置在一个上并显示另一个(JPanel 仍然为空的那个)。解决办法是不这样做,把上面几行改成:

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

或更简单地说:

addComponentToPane(frame.getContentPane());