CardLayout使用JMenu发送错误消息

时间:2012-10-16 12:44:24

标签: java swing awt layout-manager cardlayout

大家好我想创建一个简单的程序,我可以使用menuItems控制每个JPanel。例如,如果我选择File-> New,其中New是JmenuItem,它将显示名为newPanel的JPanel。此外,如果我选择Edit-> Edit,它将显示名为editPanel的JPanel以及添加到其中的对象。到目前为止,这是我构建的:

public class CardLayoutwithMenuBar extends JFrame implements ActionListener {

    private JMenuBar menu;
    private JMenu fileMenu;
    private JMenu editMenu;
    private JMenu exitMenu;

    private JMenuItem openItem;
    private JMenuItem newItem;
    private JMenuItem editItem;
    private JMenuItem exitItem;

    private JPanel newPanel;
    private JPanel openPanel;
    private JPanel editPanel;
    private JPanel exitPanel;

    static private CardLayout cardView;
    static private JPanel cardPanel;


    public CardLayoutwithMenuBar(){
        this.setVisible(true);
        this.setTitle("Controlling Different Panel Using CardLayout");
        this.setSize(400, 150);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //Create Menu bar and add to Frame
        menu = new JMenuBar();
        this.setJMenuBar(menu);

        fileMenu = new JMenu("File");
        editMenu = new JMenu("Edit");
        exitMenu = new JMenu("Exit");

        menu.add(fileMenu);
        menu.add(editMenu);
        menu.add(exitMenu);

        newItem = new JMenuItem("New File");
        openItem = new JMenuItem("File Open");
        editItem = new JMenuItem("Edit Entry");
        exitItem = new JMenuItem("Exit");

        fileMenu.add(newItem);
        fileMenu.add(openItem);
        editMenu.add(editItem);
        exitMenu.add(exitItem);

        //Declare object cardView and cardPanel and set layout of cardPanel to CardLayout
        cardView = new CardLayout();
        cardPanel = new JPanel();
        cardPanel.setLayout(cardView);


        //Create sub-panels that would correspond to each function in the menu item ex. newItem, openItem etc...
        newPanel = new JPanel();
        openPanel = new JPanel();
        editPanel = new JPanel();
        exitPanel = new JPanel();


        //add the sub-panels to the main cardpanel 
        cardPanel.add("New", newPanel);
        cardPanel.add("Open", openPanel);
        cardPanel.add("Edit",editPanel);
        cardPanel.add("Exit",exitPanel);

        newItem.addActionListener(this);
        openItem.addActionListener(this);
        editItem.addActionListener(this);
        exitItem.addActionListener(this);

        this.getContentPane().add(cardPanel, BorderLayout.CENTER);
    }

    public void actionPerformed(ActionEvent evt){
        String menuItemAction = evt.getActionCommand();

            if (menuItemAction.equals("New File")){
                cardView.show(newPanel, "New");
            }
            else if (menuItemAction.equals("File Open")){
                cardView.show(openPanel, "Open");
            }
            else if (menuItemAction.equals("Edit Entry")){
                cardView.show(editPanel, "Edit");
            }
            else if (menuItemAction.equals("Exit")){
                cardView.show(exitPanel, "Exit");
            }
            else{
                System.out.println("Opppsss you pressed something else");
        }
    }   
}

当我尝试运行此程序时,我总是收到此错误:

Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: wrong parent for CardLayout
    at java.awt.CardLayout.checkLayout(CardLayout.java:404)
    at java.awt.CardLayout.show(CardLayout.java:526)
    at com.JMenuSample.CardLayoutwithMenuBar.actionPerformed(CardLayoutwithMenuBar.java:132)
    at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2012)
    at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2335)
    at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:404)
.... and the list goes on

任何人都可以帮我解决这个问题吗?提前谢谢!

2 个答案:

答案 0 :(得分:4)

  • 必须使用CardLayout的正确方法 - public void show(Container parent, String name)

  • 然后使用cardView.show(cardPanel, "New"); (insted of cardView.show(newPanel, "New");)

  • 剩下的newPanel as Container留下来,只改变第二次。 String形式的参数

答案 1 :(得分:4)

+1到mKorbel(打败我)

然而这是:

  • 在创建setVisible之前不要致电JFrame
  • 请勿使用setSize而是找到LayoutManager getPreferredSize或覆盖JComponent
  • pack()实例
  • 上致电JFrame
  • switch上使用String阻止(来自java 7)而不是if语句,因为它更有效率
  • 不必要extend JFrame课程

错误的原因在于:

  if (menuItemAction.equals("New File")){
                cardView.show(newPanel, "New");
            }
            else if (menuItemAction.equals("File Open")){
                cardView.show(openPanel, "Open");
            }
            else if (menuItemAction.equals("Edit Entry")){
                cardView.show(editPanel, "Edit");
            }
            else if (menuItemAction.equals("Exit")){
                cardView.show(exitPanel, "Exit");
            }
            else{
                System.out.println("Opppsss you pressed something else");
        }

您的父亲是您的cardPanel,而不是您要展示的面板,由字符串参数提供:

cardView.show(cardPanel, "New");

请参阅以下更改的代码:

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class CardLayoutWithMenuBar implements ActionListener {

    private JMenuBar menu;
    private JMenu fileMenu;
    private JMenu editMenu;
    private JMenu exitMenu;
    private JMenuItem openItem;
    private JMenuItem newItem;
    private JMenuItem editItem;
    private JMenuItem exitItem;
    private JPanel newPanel;
    private JPanel openPanel;
    private JPanel editPanel;
    private JPanel exitPanel;
    private CardLayout cardView;
    private JPanel cardPanel;

    public CardLayoutWithMenuBar() {
        JFrame frame = new JFrame();
        frame.setTitle("Controlling Different Panel Using CardLayout");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        initComponents(frame);

        frame.pack();
        frame.setVisible(true);
    }

    @Override
    public void actionPerformed(ActionEvent evt) {

        String menuItemAction = evt.getActionCommand();

        switch (menuItemAction) {
            case "New File":
                cardView.show(cardPanel, "New");
                break;
            case "File Open":
                cardView.show(cardPanel, "Open");
                break;
            case "Edit Entry":
                cardView.show(cardPanel, "Edit");
                break;
            case "Exit":
                cardView.show(cardPanel, "Exit");
                break;
            default:
                System.out.println("Opppsss you pressed something else");
                break;
        }
    }

    private void initComponents(JFrame frame) {
        //Create Menu bar and add to Frame
        menu = new JMenuBar();
        frame.setJMenuBar(menu);

        fileMenu = new JMenu("File");
        editMenu = new JMenu("Edit");
        exitMenu = new JMenu("Exit");

        menu.add(fileMenu);
        menu.add(editMenu);
        menu.add(exitMenu);

        newItem = new JMenuItem("New File");
        openItem = new JMenuItem("File Open");
        editItem = new JMenuItem("Edit Entry");
        exitItem = new JMenuItem("Exit");

        fileMenu.add(newItem);
        fileMenu.add(openItem);
        editMenu.add(editItem);
        exitMenu.add(exitItem);

        //Declare object cardView and cardPanel and set layout of cardPanel to CardLayout
        cardView = new CardLayout();
        cardPanel = new JPanel(cardView);


        //Create sub-panels that would correspond to each function in the menu item ex. newItem, openItem etc...
        newPanel = new JPanel();
        openPanel = new JPanel();
        editPanel = new JPanel();
        exitPanel = new JPanel();


        //add the sub-panels to the main cardpanel 
        cardPanel.add("New", newPanel);
        cardPanel.add("Open", openPanel);
        cardPanel.add("Edit", editPanel);
        cardPanel.add("Exit", exitPanel);

        newItem.addActionListener(this);
        openItem.addActionListener(this);
        editItem.addActionListener(this);
        exitItem.addActionListener(this);

       frame.getContentPane().add(cardPanel, BorderLayout.CENTER);
    }

    public static void main(String... args) {

        //create frame and components on EDT
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                CardLayoutWithMenuBar cardLayoutWithMenuBar = new CardLayoutWithMenuBar();
            }
        });
    }
}