【问题标题】:Java CardLayout Main Menu ProblemJava CardLayout 主菜单问题
【发布时间】:2011-10-17 02:38:26
【问题描述】:

好的,我正在用 Java 开发这个名为 8 位嵌合体的游戏。我现在正在处理主菜单,但是当我使用卡片布局时,由于某种原因,窗口不会打开。这是一些代码。

import javax.swing.*;
import java.awt.*;

public class MainScreen extends JFrame{

String Title = "MainMenu";
MainMenuComp MMC = new MainMenuComp();
BreedingGround BGR = new BreedingGround();

public MainScreen() {

    setTitle("8-bit Chimera "+Title);
    setSize(800,600);
    setResizable(false);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setVisible(true);
    add(MMC);
    add(BGR);

}

public static void main(String[] args){

    new MainScreen();
    }
}

那是主窗口

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

public class MainMenuComp extends JPanel implements ActionListener{

BreedingGround BGR = new BreedingGround();
ImageData ID = new ImageData();
Image TitleBg;
Image Title;
CardLayout CL;
JButton Play;

public MainMenuComp() {

setLayout(new GridBagLayout());
GridBagConstraints GBC = new GridBagConstraints();
ImageIcon TitleData = new ImageIcon(ID.TitleSource);
ImageIcon TitleBackGroundData = new ImageIcon(ID.TitleBackGroundSource);
ImageIcon PlayData = new ImageIcon(ID.PlaySource);
TitleBg = TitleBackGroundData.getImage();
Title = TitleData.getImage();
Play = new JButton();
Play.setIcon(PlayData);
add(Play,GBC);
add(BGR,"Breed");
}

public void actionPerformed(ActionEvent AE){

    if(AE.getSource() == Play){

        CL.show(this, "Breed");
        }
    }

public void paintComponent(Graphics g){

    g.drawImage(TitleBg,0,0,800,600,this);
    g.drawImage(Title,250,80,280,140,this);
    }
}

这是卡片布局

import javax.swing.*;
import java.awt.*;

public class BreedingGround extends JPanel{

ImageData ID = new ImageData();
Image Swamp;
CardLayout CL;

public BreedingGround(){

    setLayout(new GridBagLayout());
    GridBagConstraints c = new GridBagConstraints();
    ImageIcon SwampData = new ImageIcon(ID.SwampSource);
    Swamp = SwampData.getImage();
}

public void paintComponent(Graphics g){

    g.drawImage(Swamp,0,0,800,600,this);
    }

}

这就是我希望 CardLayout 打开的内容。问题是当我尝试运行它时,窗口不会运行,并且一直显示在编译器中。

--------配置:8位Chimera - JDK版本1.6.0_26 - -------------- ------

Exception in thread "main" java.lang.IllegalArgumentException: cannot add to layout: constraints must be a GridBagConstraint
    at java.awt.GridBagLayout.addLayoutComponent(GridBagLayout.java:685)
    at java.awt.Container.addImpl(Container.java:1074)
    at java.awt.Container.add(Container.java:927)
    at MainMenuComp.<init>(MainMenuComp.java:26)
    at MainScreen.<init>(MainScreen.java:7)
    at MainScreen.main(MainScreen.java:23)

过程完成。

我真正想知道的是这是在说什么。

【问题讨论】:

    标签: java swing layout layout-manager cardlayout


    【解决方案1】:

    我看不到您曾经在哪里将容器的布局设置为 CardLayout,如果您不将布局设置为此,您将无法神奇地使用它。如果您还没有通过CardLayout tutorial,请考虑这样做,因为那里已经解释了所有内容。

    编辑 1
    来自 Alexander Kim 的评论:

    当我添加 cardbagLayout 时,它不会加载图像并且按钮大小会填满整个屏幕。我也拿走了格子

    您需要嵌套 JPanel 才能嵌套布局。使用单个 JPanel 作为 CardLayout 容器,其唯一功能是显示其他 JPanel(“卡片”)。这些其他 JPanel 将使用正确显示它们所拥有的组件所需的任何布局,例如您的 JButton 或“网格”(无论它们是什么)。甚至这些 JPanel 也可能包含使用其他布局的其他 JPanel。

    再次,请阅读布局教程,因为那里的描述都很好。你不会后悔这样做的。

    编辑 2
    这是一个使用 CardLayout 的非常简单的示例。 CardLayout 使用 JPanel 显示的组件(称为 cardContainer)会根据在组合框中选择的项目而改变。

    这是 CardLayout 和使用它的 JPanel:

    私有 CardLayout cardLayout = new CardLayout();

       // *** JPanel to hold the "cards" and to use the CardLayout:
       private JPanel cardContainer = new JPanel(cardLayout); 
    

    下面是我如何将组件添加到使用 JPanel 的卡片布局中:

      JPanel redPanel = new JPanel();
      //...
      String red = "Red Panel";
      cardContainer.add(redPanel, red); // add the JPanel to the container with the String
    

    我还将字符串添加到 JComboBox 中,以便稍后我可以使用此组合框告诉 CardLayout 如果用户在同一个 JComboBox 中选择项目“红色”,则显示此 JPanel (redPanel):

      cardCombo.addItem(red); // also add the String to the JComboBox
    

    这是 JComboBox 中的 ActionListener,它允许我使用 JPanel 更改卡片布局中显示的项目:

      cardCombo.addActionListener(new ActionListener() {
    
         public void actionPerformed(ActionEvent e) {
            String item = cardCombo.getSelectedItem().toString();
    
            // *** if combo box changes it tells the CardLayout to
            // *** swap views based on the item selected in the combo box:
            cardLayout.show(cardContainer, item);
         }
      });
    

    这是整个shebang:

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    
    public class SimpleCardLayoutDemo {
       private CardLayout cardLayout = new CardLayout();
    
       // *** JPanel to hold the "cards" and to use the CardLayout:
       private JPanel cardContainer = new JPanel(cardLayout); 
       private JComboBox cardCombo = new JComboBox();
       private JPanel comboPanel = new JPanel();;
    
       public SimpleCardLayoutDemo() {
          JPanel greenPanel = new JPanel(new BorderLayout());
          greenPanel.setBackground(Color.green);
          greenPanel.add(new JScrollPane(new JTextArea(10, 25)), BorderLayout.CENTER);
          greenPanel.setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15));
          greenPanel.add(new JButton("Bottom Button"), BorderLayout.PAGE_END);
          String green = "Green Panel";
          cardContainer.add(greenPanel, green);
          cardCombo.addItem(green);
    
          JPanel redPanel = new JPanel();
          redPanel.setBackground(Color.red);
          redPanel.add(new JButton("Foo"));
          redPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
          String red = "Red Panel";
          cardContainer.add(redPanel, red);
          cardCombo.addItem(red);
    
          JPanel bluePanel = new JPanel();
          bluePanel.setBackground(Color.blue);
          JLabel label = new JLabel("Blue Panel", SwingConstants.CENTER);
          label.setForeground(Color.white);
          label.setFont(label.getFont().deriveFont(Font.BOLD, 32f));
          bluePanel.add(label);
          String blue = "Blue Panel";
          cardContainer.add(bluePanel, blue);
          cardCombo.addItem(blue);
    
          comboPanel.add(cardCombo);
          cardCombo.addActionListener(new ActionListener() {
    
             public void actionPerformed(ActionEvent e) {
                String item = cardCombo.getSelectedItem().toString();
    
                // *** if combo box changes it tells the CardLayout to
                // *** swap views based on the item selected in the combo box:
                cardLayout.show(cardContainer, item);
             }
          });
       }
    
       public JPanel getCardContainerPanel() {
          return cardContainer;
       }
    
    
       public Component getComboPanel() {
          return comboPanel ;
       }
    
       private static void createAndShowUI() {
          SimpleCardLayoutDemo simplecardDemo = new SimpleCardLayoutDemo();
    
          JFrame frame = new JFrame("Simple CardLayout Demo");
          frame.getContentPane().add(simplecardDemo.getCardContainerPanel(), BorderLayout.CENTER);
          frame.getContentPane().add(simplecardDemo.getComboPanel(), BorderLayout.PAGE_END);
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          frame.pack();
          frame.setLocationRelativeTo(null);
          frame.setVisible(true);
       }
    
       // to run Swing in a thread-safe way
       public static void main(String[] args) {
          java.awt.EventQueue.invokeLater(new Runnable() {
             public void run() {
                createAndShowUI();
             }
          });
       }
    }
    

    【讨论】:

    • 当我添加 cardbagLayout 时,它不会加载图像并且按钮大小会填满整个屏幕。我也拿走了网格
    • @Alexander:请在上面“编辑 1”。
    • @Alexander:请参阅上面“编辑 2”中发布的示例。
    【解决方案2】:

    您的问题在于add(BGR,"Breed");。 MainMenuComp 的布局是GridBagLayout,所以约束必须是GridBagConstraint,而不是String(你有"Breed" 作为约束)。

    【讨论】:

    • 我修复了我将其更改为 cardLayout。但是按钮会填满整个屏幕。
    猜你喜欢
    • 2011-06-29
    • 1970-01-01
    • 2014-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-05
    • 2014-11-28
    • 2011-08-19
    相关资源
    最近更新 更多