带CardLayout的Java Swing GUI:返回第一张卡时,第二张卡中的窗口未关闭

带CardLayout的Java Swing GUI:返回第一张卡时,第二张卡中的窗口未关闭,java,swing,Java,Swing,我有一个Swing GUI,它使用带有两张卡的CardLayout: 主卡 走道卡 当我进入通道_卡时,它会正确切换到通道_卡并关闭主_卡: public class Runner { private static JFrame frame; private static JPanel cards; void createAndShowGUI() { //ItemsInAisleGUI gui = new ItemsInAi

我有一个Swing GUI,它使用带有两张卡的CardLayout:

  • 主卡

  • 走道卡

当我进入通道_卡时,它会正确切换到通道_卡并关闭主_卡:

public class Runner
{

    private static JFrame frame;
    private static JPanel cards;

    void createAndShowGUI()
    {
                //ItemsInAisleGUI gui = new ItemsInAisleGUI();
        // Create and set up the window.
        ItemsInAisleGUI gui = new ItemsInAisleGUI();

        frame = new JFrame("Shopping List");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        cards = new JPanel(new CardLayout());
        JPanel mainCard = buildMainPanel();

        //JPanel aisleCard = new ItemsInAisleGUI(mainCard).aisleCard;
        JPanel aisleCard = gui.createAndShowGUI();

        cards.add(mainCard, MAIN_CARD);
        cards.add(aisleCard, AISLE_CARD);
        // Display the window.
        frame.getContentPane().add(cards);
        frame.pack();
        frame.setVisible(true);
    }


    private JPanel buildMainPanel()
    {
        JPanel mainCard = new JPanel();
        mainCard.setLayout(new GridLayout());
        mainCard.setName(MAIN_CARD);
        JPanel topRowPanel = new JPanel();
        topRowPanel.setLayout(new GridLayout(12, 2));
        topRowPanel.setName("TopRowPanel");

        //Button for the Search by Aisle Card
        JButton aisleButton = new JButton("\u25BA Search by Aisle");
        aisleButton.setName(AISLE_BUTTON);
        aisleButton.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                CardLayout cl = (CardLayout) (cards.getLayout());
                cl.show(cards, AISLE_CARD);
            }
        });

        //panels and labels of mainCard

        mainCard.add(topRowPanel);
        return mainCard;
    }

    public static void main(String[] args)
    {
        javax.swing.SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                Runner r = new Runner();
                r.createAndShowGUI();
            }
        });

    }

    /**
     * @return the frame containing the application view
     */
    static JFrame getFrame()
    {

        return frame;
    }

    /**
     * @return the card that is current visible
     */
    Component getVisibleCard()
    {
        for (int i = 0; i < cards.getComponentCount(); i++)
        {
            if (cards.getComponent(i).isVisible())
            {
                return cards.getComponent(i);
            }
        }
        return null;
    }

}

有什么建议吗?谢谢。

首先,不需要静态变量。此外,您对正在发生的事情有一些误解:

它会打开主卡,但不会关闭通道卡

这是错误的。实际上,它并没有把你正在考虑的主卡挂起来。它正在打开一个全新的gui,正如您在这里的代码所示:

public void actionPerformed(ActionEvent e)
        {
            Runner myrunner = new Runner();
            myrunner.createAndShowGUI(); // Creates completely new GUI
            CloseFrame();
        }
我不知道你的应用程序的具体结构,但下面应该编译,至少应该给你一个CardLayouts如何工作的基础:

import javax.smartcardio.Card;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class Runner {

    private final JFrame frame;

    private final JPanel home;
    private final JPanel second;

    public static void main(String[] args) {
        Runner runner = new Runner();
        runner.show();
    }

    public Runner() {
        this.frame = new JFrame();
        this.frame.setSize(new Dimension(500, 500));
        this.frame.setLocationRelativeTo(null);

        JPanel contentPanel = new JPanel(new CardLayout());
        frame.setContentPane(contentPanel);

        home = buildMainPanel();
        second = buildSecondPanel();

        contentPanel.add("home", home);
        contentPanel.add("second", second);

    }

    public JPanel buildMainPanel() {
        JPanel something = new JPanel(null);
        something.setBounds(0,0,500,500);
        something.setBackground(Color.black);

        JButton flipButton = new JButton("Second");
        flipButton.setBounds(0,0,100,80);
        flipButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                CardLayout layout = (CardLayout) frame.getContentPane().getLayout();
                layout.show(frame.getContentPane(), "second");
            }
        });

        something.add(flipButton);
        return something;
    }

    public JPanel buildSecondPanel() {
        JPanel something = new JPanel(null);
        something.setBounds(0,0,500,500);
        something.setBackground(Color.blue);

        JButton flipButton = new JButton("Second");
        flipButton.setBounds(0,0,100,80);
        flipButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                CardLayout layout = (CardLayout) frame.getContentPane().getLayout();
                layout.show(frame.getContentPane(), "home");
            }
        });

        something.add(flipButton);
        return something;
    }

    public void show() {
        frame.setVisible(true);
    }
}

如果您编译此文件并点击按钮,您可以看到背景从黑色翻转到蓝色,这意味着显示的是不同的卡片。希望这有助于您走上正确的道路。

这可能不是问题的症结所在,但您是否将aislebutton添加到父组件中?这意味着变量
jFrame
为空。我看不到您将此变量设置为null的任何地方(甚至就这一点而言,它被声明为类
JFrame
的实例。因此,我认为问题可能出在您尚未演示的其他代码中。@NoseKnowall我忘了提到我在ItemsinAisleGUI类中声明了
private static JFrame
。如果第二张卡在单独的类中,这将如何工作解决的办法是,该类将具有一个getDisplay()函数,该函数将返回该类所表示的面板,但由于维护的原因,人们通常不赞成这样做。
import javax.smartcardio.Card;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class Runner {

    private final JFrame frame;

    private final JPanel home;
    private final JPanel second;

    public static void main(String[] args) {
        Runner runner = new Runner();
        runner.show();
    }

    public Runner() {
        this.frame = new JFrame();
        this.frame.setSize(new Dimension(500, 500));
        this.frame.setLocationRelativeTo(null);

        JPanel contentPanel = new JPanel(new CardLayout());
        frame.setContentPane(contentPanel);

        home = buildMainPanel();
        second = buildSecondPanel();

        contentPanel.add("home", home);
        contentPanel.add("second", second);

    }

    public JPanel buildMainPanel() {
        JPanel something = new JPanel(null);
        something.setBounds(0,0,500,500);
        something.setBackground(Color.black);

        JButton flipButton = new JButton("Second");
        flipButton.setBounds(0,0,100,80);
        flipButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                CardLayout layout = (CardLayout) frame.getContentPane().getLayout();
                layout.show(frame.getContentPane(), "second");
            }
        });

        something.add(flipButton);
        return something;
    }

    public JPanel buildSecondPanel() {
        JPanel something = new JPanel(null);
        something.setBounds(0,0,500,500);
        something.setBackground(Color.blue);

        JButton flipButton = new JButton("Second");
        flipButton.setBounds(0,0,100,80);
        flipButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                CardLayout layout = (CardLayout) frame.getContentPane().getLayout();
                layout.show(frame.getContentPane(), "home");
            }
        });

        something.add(flipButton);
        return something;
    }

    public void show() {
        frame.setVisible(true);
    }
}