CardLayout 问题

CardLayout issue

提问人:Peddler 提问时间:3/17/2012 最后编辑:Peddler 更新时间:3/20/2012 访问量:1881

问:

我有一个卡片布局,第一张卡片是一个菜单。

我选择第二张牌,然后执行一些操作。我们将说通过单击按钮来添加 JTextField。如果我返回菜单卡,然后返回到第二张卡,那么我第一次添加的 JTextField 仍将存在。

我希望第二张卡片在每次访问时都与我最初构建的卡片相同,带有按钮,但没有文本字段。

Java Swing JPan面板 CardLayout

评论

0赞 Andrew Thompson 3/17/2012
如果“最初构造”意味着“空白/无组件”,那么添加新卡似乎更有意义。
0赞 nIcE cOw 3/17/2012
只需使用 removeLayoutComponent(...) 从 中删除当前卡,在上一个按钮单击时,然后使用 [addLayoutComponent(...)] 添加该卡的新实例(docs.oracle.com/javase/7/docs/api/java/awt/..., java.lang.Object))。Layout
0赞 Peddler 3/17/2012
@AndrewThompson也许我不清楚......我的第二张卡片上有按钮,当单击这些按钮时,会出现一个文本字段,如果我返回第一张卡片,然后再次返回第二张卡片,文本字段仍将存在。我希望第二张卡片在每次访问时都与我最初构建的卡片一样,带有按钮,没有文本字段
1赞 nIcE cOw 3/17/2012
@Peddler : 我实际上正在研究这件事,我刚刚在测试时意识到你的问题:-)
1赞 Hovercraft Full Of Eels 3/17/2012
如果你能创建并发布一个sscce,那就太好了。

答:

1赞 Eric Hydrick 3/17/2012 #1

确保您尝试重置的面板具有将其恢复到“最初构造”状态的代码。然后,在处理导致您更换卡片的 whatever 事件时,请在显示卡片之前调用该代码以恢复原始状态。

1赞 nIcE cOw 3/20/2012 #2

这是最终整理出来的版本,要删除卡片,在对其进行更改后,请看一看,像往常一样使用和东西:-)revalidate()repaint()

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

public class ApplicationBase extends JFrame
{
    private JPanel centerPanel;
    private int topPanelCount = 0;

    private String[] cardNames = {
                                                        "Login Window",
                                                        "TextField Creation"
                                                   };

    private TextFieldCreation tfc;
    private LoginWindow lw;

    private JButton nextButton;
    private JButton removeButton;

    private ActionListener actionListener = new ActionListener()
    {
        public void actionPerformed(ActionEvent ae)
        {
            if (ae.getSource() == nextButton)
            {   
                    CardLayout cardLayout = (CardLayout) centerPanel.getLayout();
                    cardLayout.next(centerPanel);
            }
            else if (ae.getSource() == removeButton)
            {
                    centerPanel.remove(tfc);
                    centerPanel.revalidate();
                    centerPanel.repaint();
                    tfc = new TextFieldCreation();
                    tfc.createAndDisplayGUI();  
                    centerPanel.add(tfc, cardNames[1]);
            }
        }
    };

    private void createAndDisplayGUI()
    {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationByPlatform(true);

        centerPanel = new JPanel();
        centerPanel.setLayout(new CardLayout());

        lw = new LoginWindow();
        lw.createAndDisplayGUI();
        centerPanel.add(lw, cardNames[0]);
        tfc = new TextFieldCreation();
        tfc.createAndDisplayGUI();
        centerPanel.add(tfc, cardNames[1]);

        JPanel bottomPanel = new JPanel();
        removeButton = new JButton("REMOVE");
        nextButton = new JButton("NEXT");       
        removeButton.addActionListener(actionListener);
        nextButton.addActionListener(actionListener);

        bottomPanel.add(removeButton);
        bottomPanel.add(nextButton);

        add(centerPanel, BorderLayout.CENTER);
        add(bottomPanel, BorderLayout.PAGE_END);

        pack();
        setVisible(true);
    }

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

class TextFieldCreation extends JPanel
{
    private JButton createButton;
    private int count = 0;

    public void createAndDisplayGUI()
    {
        final JPanel topPanel = new JPanel();
        topPanel.setLayout(new GridLayout(0, 2));

        createButton = new JButton("CREATE TEXTFIELD");
        createButton.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent ae)
            {
                JTextField tfield = new JTextField();
                tfield.setActionCommand("JTextField" + count);

                topPanel.add(tfield);
                topPanel.revalidate();
                topPanel.repaint();
            }
        });

        setLayout(new BorderLayout(5, 5));
        add(topPanel, BorderLayout.CENTER);
        add(createButton, BorderLayout.PAGE_END);
    }
}

class LoginWindow extends JPanel
{
    private JPanel topPanel;
    private JPanel middlePanel;
    private JPanel bottomPanel;

    public void createAndDisplayGUI()
    {
        topPanel = new JPanel();

        JLabel userLabel = new JLabel("USERNAME : ", JLabel.CENTER);
        JTextField userField = new JTextField(20);
        topPanel.add(userLabel);
        topPanel.add(userField);

        middlePanel = new JPanel();

        JLabel passLabel = new JLabel("PASSWORD : ", JLabel.CENTER);
        JTextField passField = new JTextField(20);
        middlePanel.add(passLabel);
        middlePanel.add(passField);

        bottomPanel = new JPanel();

        JButton loginButton = new JButton("LGOIN");
        bottomPanel.add(loginButton);

        setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
        add(topPanel);
        add(middlePanel);
        add(bottomPanel);
    }
}

如果您只想删除 made to the card,请尝试以下代码:Latest Edit

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

public class ApplicationBase extends JFrame
{
    private JPanel centerPanel;
    private int topPanelCount = 0;

    private String[] cardNames = {
                                                        "Login Window",
                                                        "TextField Creation"
                                                   };

    private TextFieldCreation tfc;
    private LoginWindow lw;

    private JButton nextButton;
    private JButton removeButton;

    private ActionListener actionListener = new ActionListener()
    {
        public void actionPerformed(ActionEvent ae)
        {
            if (ae.getSource() == nextButton)
            {   
                    CardLayout cardLayout = (CardLayout) centerPanel.getLayout();
                    cardLayout.next(centerPanel);
            }
            else if (ae.getSource() == removeButton)
            {
                    TextFieldCreation.topPanel.remove(TextFieldCreation.tfield);
                    TextFieldCreation.topPanel.revalidate();
                    TextFieldCreation.topPanel.repaint();
            }
        }
    };

    private void createAndDisplayGUI()
    {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationByPlatform(true);

        centerPanel = new JPanel();
        centerPanel.setLayout(new CardLayout());

        lw = new LoginWindow();
        lw.createAndDisplayGUI();
        centerPanel.add(lw, cardNames[0]);
        tfc = new TextFieldCreation();
        tfc.createAndDisplayGUI();
        centerPanel.add(tfc, cardNames[1]);

        JPanel bottomPanel = new JPanel();
        removeButton = new JButton("REMOVE");
        nextButton = new JButton("NEXT");       
        removeButton.addActionListener(actionListener);
        nextButton.addActionListener(actionListener);

        bottomPanel.add(removeButton);
        bottomPanel.add(nextButton);

        add(centerPanel, BorderLayout.CENTER);
        add(bottomPanel, BorderLayout.PAGE_END);

        pack();
        setVisible(true);
    }

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

class TextFieldCreation extends JPanel
{
    private JButton createButton;
    private int count = 0;
    public static JTextField tfield;
    public static JPanel topPanel;

    public void createAndDisplayGUI()
    {
        topPanel = new JPanel();
        topPanel.setLayout(new GridLayout(0, 2));

        createButton = new JButton("CREATE TEXTFIELD");
        createButton.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent ae)
            {
                tfield = new JTextField();
                tfield.setActionCommand("JTextField" + count);

                topPanel.add(tfield);
                topPanel.revalidate();
                topPanel.repaint();
            }
        });

        setLayout(new BorderLayout(5, 5));
        add(topPanel, BorderLayout.CENTER);
        add(createButton, BorderLayout.PAGE_END);
    }
}

class LoginWindow extends JPanel
{
    private JPanel topPanel;
    private JPanel middlePanel;
    private JPanel bottomPanel;

    public void createAndDisplayGUI()
    {
        topPanel = new JPanel();

        JLabel userLabel = new JLabel("USERNAME : ", JLabel.CENTER);
        JTextField userField = new JTextField(20);
        topPanel.add(userLabel);
        topPanel.add(userField);

        middlePanel = new JPanel();

        JLabel passLabel = new JLabel("PASSWORD : ", JLabel.CENTER);
        JTextField passField = new JTextField(20);
        middlePanel.add(passLabel);
        middlePanel.add(passField);

        bottomPanel = new JPanel();

        JButton loginButton = new JButton("LGOIN");
        bottomPanel.add(loginButton);

        setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
        add(topPanel);
        add(middlePanel);
        add(bottomPanel);
    }
}

评论

0赞 Hovercraft Full Of Eels 3/20/2012
如果不从 CardLayout 中删除组件,而是将其从容器本身 (centerPanel) 中删除,该怎么办?
0赞 nIcE cOw 3/20/2012
@HovercraftFullOfEels : 是的,按预期将其直接从工作正常中删除。所以某个地方没有按应有的方式执行:-)感谢您抽出宝贵时间查看代码。centerPanelCardLayout
0赞 kleopatra 3/20/2012
这不是一个错误,这是一个用户错误(IMO,可能是我不太明白:)从其父组件中删除组件的方法始终是调用 parent.remove(...),它在内部向 layout.removeLayoutComponent 发送消息,后者会自行清理。因此,如果应用程序代码调用后者,则该组件仍位于父级的子树中,这可能会也可能不会混淆某些协作者。@Hovercraft很好的收获:-)
0赞 nIcE cOw 3/20/2012
但问题来了,当这些事情要手工完成时,我的意思是手动完成,那么这两种方法的用途是什么,它们有时会删除,天知道,似乎他们在做工作时喜怒无常:-)。这肯定是一个错误,否则为什么要使用为什么不做旧样式,当我们必须这样做时,在删除卡片时,为什么不对添加卡片也做同样的事情。CardLayoutrevalidate()repaint()
1赞 kleopatra 3/20/2012
它们供框架本身使用,即供容器使用,而不是供应用程序代码使用。所有 LayoutManager 都有这些方法,但你从不使用它们 - 那么为什么你认为你应该在 CardLayout 的情况下使用它们。根本就不要