如何使用 CardLayout,将 Menu 作为动作侦听器?

How to use CardLayout, with Menu as action listener?

我想使用 CardLayout class 更改 JFrame 的 JPanel。 我已经有 运行 this 示例并且它有效。

现在我想将 JMenuItem 用作动作侦听器;所以如果我按下那个 JMenuItem,我想用一个特定的面板来改变它。所以这是 JFrame:

public class FantaFrame extends JFrame implements Observer {

    private static final long serialVersionUID = 1L;
    private JPanel cardPanel = new JPanel();
    private CardLayout cardLayout = new CardLayout();

    public FantaFrame(HashMap<String, JPanel> fantaPanels) {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setTitle("FantaCalcio App");
        setSize(500, 500);
        cardPanel.setLayout(cardLayout);
        setPanels(fantaPanels);

    }

    public void update(Observable o, Object arg) {
        cardLayout.show(cardPanel, arg.toString());
    }

    private void setPanels(HashMap<String, JPanel> fantaPanels) {
        for (String name : fantaPanels.keySet()) {
            cardPanel.add(fantaPanels.get(name), name);
        }
    }
}

这些是菜单、控制器和主菜单:

    private void pressed(){
        home.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                controller.changePanel(home.getText());
            }
        });
    }
   public class Controller extends Observable {


    public void changePanel(String panel){
        setChanged();
        notifyObservers(panel);
    }
}
    public static void main(String[] args) {
        fantaPanels.put("Login", new LoginPanel());
        Controller controller = new Controller();
        MenuBarApp menuApp = new MenuBarApp(controller);
        FantaFrame frame = new FantaFrame(fantaPanels);
        frame.setJMenuBar(menuApp);
        controller.addObserver(frame);
        frame.setVisible(true);
    }

问题是 JPanel 没有改变。你认为问题是什么? 我已经调试过了,在 update() 方法中,正确的 String 值到达了。

您永远不会添加 cardPanel JPanel,它使用 CardLayout 并显示 "cards" 到任何东西。您需要将它添加到 JFrame 的 contentPane 才能显示任何内容。即

public FantaFrame(HashMap<String, JPanel> fantaPanels) {
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setTitle("FantaCalcio App");
    setSize(500, 500);
    cardPanel.setLayout(cardLayout);
    add(cardPanel, BorderLayout.CENTER); // ****** add this line ******
    setPanels(fantaPanels);
}