我正在尝试创建一个从一个面板移动到另一个面板的程序,并在每个面板中用户回答一个问题。我目前正在尝试使用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。我做错了,应该改变我的吗?
编辑:我改变了我的代码以反映建议
答案 0 :(得分:2)
您需要替换此行:
frame.getContentPane().setLayout(new CardLayout(0, 0));
有了这个:
frame.getContentPane().setLayout(cl);
目前编写的方式是,您将框架的布局设置为全新的CardLayout,而不是使用您创建并分配给cl
变量的布局。
答案 1 :(得分:1)
当您只需要一个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;
}
}