带有next()的CardLayout IllegalArgumentException

时间:2017-02-17 02:57:19

标签: java swing layout-manager illegalargumentexception cardlayout

我正在尝试创建一个从一个面板移动到另一个面板的程序,并在每个面板中用户回答一个问题。我目前正在尝试使用next()切换卡片,但它给我一个IllegalArgumentException问题。

我已经将我的代码简化为我的问题的基础,以便为问题找不到代码。 我的主要类是箭头,我的第二个类是Flash,因为我希望每个面板都是它自己的物理文件。我试图在Flash中调用相同的next()函数,效果相同,即使技术上不是第三个面板。

这是箭头(主要)

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

public class Arrow{
public JPanel panelHouse;
public JFrame frame = new JFrame();
public int total = 3000;

public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                Arrow window = new Arrow();
                window.frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            } } }); } //putting all the closing brackets on one line saves space. This is test code so it doesn't matter to me
public Arrow() {
    initialize();
}
public Arrow(int x){
    //this is here so I don't run initialize when I need to create an Arrow variable in other classes
    //it doesn't actually do anything
}

private void initialize() {
    CardLayout cl = new CardLayout(0, 0);
    frame.setBounds(400, 400, 909, 572);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().setLayout(cl);

    JPanel panelHouse = new JPanel();
    panelHouse.setBounds(0, 0, 10, 10);
    frame.getContentPane().add(panelHouse, "Housing");
    panelHouse.setLayout(null);

    Flash Flash1 = new Flash();
    frame.getContentPane().add(Flash1, "Flash");
    Flash1.setLayout(null);

    JButton btnHouseNext = new JButton("NEXT STATION");
    btnHouseNext.setFont(new Font("Times New Roman", Font.PLAIN, 20));
    btnHouseNext.setBounds(344, 371, 184, 48);
    btnHouseNext.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent ae) { 
            cl.next(frame);
        }
    });//Close housingNext button actionlistener
    panelHouse.add(btnHouseNext);
}//close initialize

public JPanel getPanelHouse() {
    return panelHouse;
}

public JFrame getFrame(){
    return frame;
}
}//close class body

这是Flash(第二个面板)

package layout;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class Flash extends JPanel{
    private CardLayout cardLayout = new CardLayout();
    private static final long serialVersionUID = 1L;
    public Flash() {
        Arrow a = new Arrow(4);
        JPanel Flash1 = new JPanel();
        setBounds(0, 0, 10, 10);
        setLayout(null);
        setBackground(Color.orange);

        JButton buttonFlash = new JButton("NEXT STATION");
        buttonFlash.setFont(new Font("Times New Roman", Font.PLAIN, 20));
        buttonFlash.setBounds(344, 371, 184, 48);
        buttonFlash.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {
            Flash1.setVisible(false);
            cardLayout.next(a.getFrame());
            }
        });
        add(buttonFlash);
        setVisible(true);
        }   
}

这是我的错误堆栈跟踪

Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: wrong parent for CardLayout
at java.awt.CardLayout.checkLayout(Unknown Source)
at java.awt.CardLayout.next(Unknown Source)
at layout.Arrow$2.actionPerformed(Arrow.java:48)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$500(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)

现在我也看到了代码,其容器是JPanel而不是像我这样的JFrame。我做错了,应该改变我的吗?

编辑:我改变了我的代码以反映建议

2 个答案:

答案 0 :(得分:2)

您需要替换此行:

frame.getContentPane().setLayout(new CardLayout(0, 0));

有了这个:

frame.getContentPane().setLayout(cl);

目前编写的方式是,您将框架的布局设置为全新的CardLayout,而不是使用您创建并分配给cl变量的布局。

答案 1 :(得分:1)

当您只需要一个CardLayout实例时,您创建的实例太多了。建议:

  • 将CardLayout设为正在使用它的类的字段
  • 为同一个类提供一个公共方法,比如称为public void next(),您可以使用CardLayout交换JPanel。
  • 在需要时调用该方法。

例如:

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;

import javax.swing.*;

public class Flash extends JPanel {
    private Arrow arrow = new Arrow();

    public Flash() {
        JPanel btnPanel = new JPanel();
        btnPanel.add(new JButton(new NextAction("Next")));            

        setLayout(new BorderLayout());
        add(arrow, BorderLayout.CENTER);
        add(btnPanel, BorderLayout.PAGE_END);
    }

    private class NextAction extends AbstractAction {
        public NextAction(String name) {
            super(name);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            arrow.next();  // *** call arrow's public next method that you created

            // no need to make a new CardLayout instance
        }
    }

    private static void createAndShowGui() {
        Flash mainPanel = new Flash();

        JFrame frame = new JFrame("SimpleCardLayout");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}

class Arrow extends JPanel {
    private CardLayout cardLayout = new CardLayout(); // make me a field
    private JPanel cardHolder = new JPanel(cardLayout);

    public Arrow() {
        for (int i = 0; i < 5; i++) {
            cardHolder.add(createCard(i), "card " + i);
        }

        setLayout(new BorderLayout());
        add(cardHolder, BorderLayout.CENTER);
    }

    // public method that other objects can call
    public void next() {
        cardLayout.next(cardHolder);  // call next on the correct object
    }

    // simply creates a "pretty" new JPanel
    private JComponent createCard(int i) {
        JLabel label = new JLabel("Card " + i);
        label.setFont(label.getFont().deriveFont(Font.BOLD, 50f));

        float h = (float)Math.random();
        Color c = Color.getHSBColor(h, 1f, 1f);
        label.setForeground(c.darker());

        JPanel panel = new JPanel(new GridBagLayout());
        panel.add(label);
        panel.setBorder(BorderFactory.createLineBorder(c.darker(), 20));
        panel.setBackground(c.brighter().brighter());

        panel.setPreferredSize(new Dimension(400, 300));
        return panel;
    }
}