JPanels 不会出现在 Cardlayout 容器中

JPanels won't show up in Cardlayout container

我正在尝试创建多个 JPanel,它们会在按下按钮时打开。我尝试按照本教程进行操作

http://java.about.com/od/Layout_Managers/ss/Cardlayout-Example-Program.htm

但是我的程序不工作。框架打开,里面什么也没有。一旦我可以让它工作,我将添加更多的面板类。

import java.awt.event.*;
import java.awt.*;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javafx.scene.layout.Border;
import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.border.LineBorder;
import javax.swing.Box;
import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
import javax.swing.JTextArea;
import javax.swing.Icon;
import javax.swing.*;

public class CardLayoutExample
{
    private JPanel contentPane;
    private MyPanel1 panel1;
    private MyPanel2 panel2;
    CardLayout cl;

    private void displayGUI()
     {
        JFrame frame = new JFrame("Card Layout Example");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new BorderLayout());

        cl = new CardLayout();
        JPanel contentPane = new JPanel();
        contentPane.setLayout(cl);
        cl.show(contentPane, "Panel 1");
        panel1 = new MyPanel1();
        panel2 = new MyPanel2();
        contentPane.add(panel1, "Panel 1");
        contentPane.add(panel2, "Panel 2");
        frame.add(contentPane,BorderLayout.NORTH); 
        //frame.setContentPane(contentPane);
        frame.pack();   
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public void addItem(JPanel p, JComponent c, int x, int y, int width, int height, int align) {
        GridBagConstraints gc = new GridBagConstraints();
        gc.gridx = x;
        gc.gridy = y;
        gc.gridwidth = width;
        gc.gridheight = height;
        gc.weightx = 100.0;
        gc.weighty = 100.0;
        gc.insets = new Insets(5, 5, 5, 5);
        gc.anchor = align;
        gc.fill = GridBagConstraints.NONE;
        p.add(c, gc);
    } 

    public static void main(String... args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                new CardLayoutExample().displayGUI();
            }
        });
    }
}

class MyPanel1 extends JPanel {

    private JPanel contentPane;
    JTextField JTextfield1 = new JTextField(15), JTextfield2 = new JTextField(15);
    JTextArea Discription = new JTextArea(4,30);

    public MyPanel1() {

        contentPane = new JPanel();
        contentPane.setLayout(new GridBagLayout());
        contentPane.setBackground(Color.WHITE);

      //add components
        addItem(contentPane, new JLabel("Sample ID:"), 0, 0, 1, 1, GridBagConstraints.SOUTHWEST);
        addItem(contentPane, new JLabel("User ID:"), 1, 0, 1, 1, GridBagConstraints.SOUTHWEST);
        addItem(contentPane, new JLabel("Bone Description:"), 0, 2, 1, 1, GridBagConstraints.SOUTHWEST);

        addItem(contentPane, JTextfield1, 0, 1, 1, 1, GridBagConstraints.NORTHWEST);
        addItem(contentPane, JTextfield2, 1, 1, 1, 1, GridBagConstraints.NORTHWEST);
        addItem(contentPane, Discription, 0, 3, 1, 1, GridBagConstraints.WEST);

        Icon nextIcon = new ImageIcon("arrow.jpeg");
        JButton nextButton = new JButton("Next", nextIcon);
        addItem(contentPane, nextButton, 1, 4, 1, 1, GridBagConstraints.NORTHEAST);
        nextButton.addActionListener( new ActionListener(){
        public void actionPerformed(ActionEvent e)
        {
            CardLayout cardLayout = (CardLayout) contentPane.getLayout();
            cardLayout.show(contentPane, "Panel 2");
        }
    });
}

    public void addItem(JPanel p, JComponent c, int x, int y, int width, int height, int align) {
        GridBagConstraints gc = new GridBagConstraints();
        gc.gridx = x;
        gc.gridy = y;
        gc.gridwidth = width;
        gc.gridheight = height;
        gc.weightx = 100.0;
        gc.weighty = 100.0;
        gc.insets = new Insets(5, 5, 5, 5);
        gc.anchor = align;
        gc.fill = GridBagConstraints.NONE;
        p.add(c, gc);
    } 
}

class MyPanel2 extends JPanel {

    public MyPanel2() {
        System.out.print("asdf");    
    }

    public void addItem(JPanel p, JComponent c, int x, int y, int width, int height, int align) {
        GridBagConstraints gc = new GridBagConstraints();
        gc.gridx = x;
        gc.gridy = y;
        gc.gridwidth = width;
        gc.gridheight = height;
        gc.weightx = 100.0;
        gc.weighty = 100.0;
        gc.insets = new Insets(5, 5, 5, 5);
        gc.anchor = align;
        gc.fill = GridBagConstraints.NONE;
        p.add(c, gc);
    }
}

这里的基本问题是 MyPanel1 既扩展了 JPanel 又有一个 JPanel 作为 class 的成员。

我的建议是不要扩展面板,而是使用声明为属性的contentPane。扩展 class 是我们在更改 class 的行为或添加功能时应该做的事情,这里没有发生任何事情。

接下来要解决的问题,会是这样的:

    public void actionPerformed(ActionEvent e)
    {
        CardLayout cardLayout = (CardLayout) contentPane.getLayout();
        cardLayout.show(contentPane, "Panel 2");
    }

更新

这是我的第一个建议(很糟糕 - 应该有一个 get 方法来获取实际的面板)。它还指出了第二个问题的修复。

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

public class CardLayoutExample
{
    private MyPanel1 panel1;
    private MyPanel2 panel2;
    CardLayout cl;

    private void displayGUI()
     {
        JFrame frame = new JFrame("Card Layout Example");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new BorderLayout());

        cl = new CardLayout();
        JPanel contentPane = new JPanel();
        contentPane.setLayout(cl);
        cl.show(contentPane, "Panel 1");
        panel1 = new MyPanel1();
        panel2 = new MyPanel2();
        contentPane.add(panel1.contentPane, "Panel 1");
        contentPane.add(panel2, "Panel 2");
        frame.add(contentPane,BorderLayout.NORTH); 
        //frame.setContentPane(contentPane);
        frame.pack();   
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public void addItem(JPanel p, JComponent c, int x, int y, int width, int height, int align) {
        GridBagConstraints gc = new GridBagConstraints();
        gc.gridx = x;
        gc.gridy = y;
        gc.gridwidth = width;
        gc.gridheight = height;
        gc.weightx = 100.0;
        gc.weighty = 100.0;
        gc.insets = new Insets(5, 5, 5, 5);
        gc.anchor = align;
        gc.fill = GridBagConstraints.NONE;
        p.add(c, gc);
    } 

    public static void main(String... args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                new CardLayoutExample().displayGUI();
            }
        });
    }
}

class MyPanel1 {

    JPanel contentPane;
    JTextField JTextfield1 = new JTextField(15), JTextfield2 = new JTextField(15);
    JTextArea Discription = new JTextArea(4,30);

    public MyPanel1() {

        contentPane = new JPanel();
        contentPane.setLayout(new GridBagLayout());
        contentPane.setBackground(Color.WHITE);

      //add components
        addItem(contentPane, new JLabel("Sample ID:"), 0, 0, 1, 1, GridBagConstraints.SOUTHWEST);
        addItem(contentPane, new JLabel("User ID:"), 1, 0, 1, 1, GridBagConstraints.SOUTHWEST);
        addItem(contentPane, new JLabel("Bone Description:"), 0, 2, 1, 1, GridBagConstraints.SOUTHWEST);

        addItem(contentPane, JTextfield1, 0, 1, 1, 1, GridBagConstraints.NORTHWEST);
        addItem(contentPane, JTextfield2, 1, 1, 1, 1, GridBagConstraints.NORTHWEST);
        addItem(contentPane, Discription, 0, 3, 1, 1, GridBagConstraints.WEST);

        Icon nextIcon = new ImageIcon("arrow.jpeg");
        JButton nextButton = new JButton("Next", nextIcon);
        addItem(contentPane, nextButton, 1, 4, 1, 1, GridBagConstraints.NORTHEAST);
        nextButton.addActionListener( new ActionListener(){
        public void actionPerformed(ActionEvent e)
        {
            CardLayout cardLayout = (CardLayout) contentPane.getParent().getLayout();
            cardLayout.show(contentPane.getParent(), "Panel 2");
        }
    });
}

    public void addItem(JPanel p, JComponent c, int x, int y, int width, int height, int align) {
        GridBagConstraints gc = new GridBagConstraints();
        gc.gridx = x;
        gc.gridy = y;
        gc.gridwidth = width;
        gc.gridheight = height;
        gc.weightx = 100.0;
        gc.weighty = 100.0;
        gc.insets = new Insets(5, 5, 5, 5);
        gc.anchor = align;
        gc.fill = GridBagConstraints.NONE;
        p.add(c, gc);
    } 
}

class MyPanel2 extends JPanel {

    public MyPanel2() {
        setBackground(Color.red);
    }

    public void addItem(JPanel p, JComponent c, int x, int y, int width, int height, int align) {
        GridBagConstraints gc = new GridBagConstraints();
        gc.gridx = x;
        gc.gridy = y;
        gc.gridwidth = width;
        gc.gridheight = height;
        gc.weightx = 100.0;
        gc.weighty = 100.0;
        gc.insets = new Insets(5, 5, 5, 5);
        gc.anchor = align;
        gc.fill = GridBagConstraints.NONE;
        p.add(c, gc);
    }
}

您不需要在 MyPanel1 中引用 contentPane。您可以只使用面板本身。请改用 this。仔细检查 MyPanel1 class 以及 actionPerformed 方法,它获取包含两个 JPanel 的父级的引用。还要检查 dislplayGUI 方法。您应该只在添加所有卡片后调用 show。默认情况下,它将显示第一个。但是如果你想在启动时显示一些其他的面板,那就很重要了。

public class CardLayoutExample
{

 private void displayGUI()
 {


    contentPane.add(panel1, "Panel 1");
    contentPane.add(panel2, "Panel 2");
    // call show after adding not before 
    cl.show(contentPane, "Panel 1");
}
// same as before only change in MyPanel1
..........
class MyPanel1 extends JPanel {

    JTextField JTextfield1 = new JTextField(15), JTextfield2 = new JTextField(15);
    JTextArea Discription = new JTextArea(4,30);

    public MyPanel1() {


        //add components, use THIS to refer to the current JPanel which is MyPanel1
        addItem(this, new JLabel("Sample ID:"), 0, 0, 1, 1, GridBagConstraints.SOUTHWEST);
        addItem(this, new JLabel("User ID:"), 1, 0, 1, 1, GridBagConstraints.SOUTHWEST);
        addItem(this, new JLabel("Bone Description:"), 0, 2, 1, 1, GridBagConstraints.SOUTHWEST);

        addItem(this, JTextfield1, 0, 1, 1, 1, GridBagConstraints.NORTHWEST);
        addItem(this, JTextfield2, 1, 1, 1, 1, GridBagConstraints.NORTHWEST);
        addItem(this, Discription, 0, 3, 1, 1, GridBagConstraints.WEST);

        Icon nextIcon = new ImageIcon("arrow.jpeg");
        JButton nextButton = new JButton("Next", nextIcon);
        addItem(this, nextButton, 1, 4, 1, 1, GridBagConstraints.NORTHEAST);
        nextButton.addActionListener( new ActionListener(){
        public void actionPerformed(ActionEvent e)
        {
            // this gets the CardLayout from Parent of the Panel
            CardLayout cardLayout = (CardLayout) MyPanel1.this.getParent().getLayout();
            cardLayout.show(MyPanel1.this.getParent(), "Panel 2");
        }
    });
}

    public void addItem(JPanel p, JComponent c, int x, int y, int width, int height, int align) {
        GridBagConstraints gc = new GridBagConstraints();
        gc.gridx = x;
        gc.gridy = y;
        gc.gridwidth = width;
        gc.gridheight = height;
        gc.weightx = 100.0;
        gc.weighty = 100.0;
        gc.insets = new Insets(5, 5, 5, 5);
        gc.anchor = align;
        gc.fill = GridBagConstraints.NONE;
        p.add(c, gc);
    } 
}

class MyPanel2 extends JPanel {

    public MyPanel2() {
        // for testing if Panel 2 shows up
        addItem(this, new JLabel("Panel 2:"), 0, 0, 1, 1, GridBagConstraints.SOUTHWEST);
    }

    public void addItem(JPanel p, JComponent c, int x, int y, int width, int height, int align) {
        GridBagConstraints gc = new GridBagConstraints();
        gc.gridx = x;
        gc.gridy = y;
        gc.gridwidth = width;
        gc.gridheight = height;
        gc.weightx = 100.0;
        gc.weighty = 100.0;
        gc.insets = new Insets(5, 5, 5, 5);
        gc.anchor = align;
        gc.fill = GridBagConstraints.NONE;
        p.add(c, gc);

    }
}