# 如何使用 CardLayout

> 原文： [https://docs.oracle.com/javase/tutorial/uiswing/layout/card.html](https://docs.oracle.com/javase/tutorial/uiswing/layout/card.html)

* * *

**Note:** This lesson covers writing layout code by hand, which can be challenging. If you are not interested in learning all the details of layout management, you might prefer to use the `GroupLayout` layout manager combined with a builder tool to lay out your GUI. One such builder tool is the [NetBeans IDE](../learn/index.html). Otherwise, if you want to code by hand and do not want to use `GroupLayout`, then `GridBagLayout` is recommended as the next most flexible and powerful layout manager.

* * *

如果您对使用 JavaFX 创建 GUI 感兴趣，请参阅[在 JavaFX](https://docs.oracle.com/javase/8/javafx/layout-tutorial/index.html) 中使用布局。

下图表示使用 [`CardLayout`](https://docs.oracle.com/javase/8/docs/api/java/awt/CardLayout.html) 类在两个面板之间切换的应用程序的快照。

![A snapshot of CardLayoutDemo](img/26aec8afefd1f2f5326323d57942ca0a.jpg) ![Another snapshot of CardLayoutDemo](img/3b53a2bceda4ff23a72ba9b204c40c0b.jpg)

单击“启动”按钮以使用 [Java™Web Start](http://www.oracle.com/technetwork/java/javase/javawebstart/index.html) （[下载 Java SE](http://www.oracle.com/technetwork/java/javase/downloads/index.html) ）运行 CardLayoutDemo。或者，要自己编译并运行示例，请参考[示例索引](../examples/layout/index.html#CardLayoutDemo)。

[![Launches the CardLayoutDemo application](img/4707a69a17729d71c56b2bdbbb4cc61c.jpg)](https://docs.oracle.com/javase/tutorialJWS/samples/uiswing/CardLayoutDemoProject/CardLayoutDemo.jnlp)

该演示的完整代码位于 [`CardLayoutDemo.java`](../examples/layout/CardLayoutDemoProject/src/layout/CardLayoutDemo.java) 文件中。

`CardLayout`类管理共享相同显示空间的两个或多个组件（通常是`JPanel`实例）。使用`CardLayout`类时，让用户使用组合框在组件之间进行选择。 `CardLayoutDemo`应用程序是用于说明此功能的示例。

完成相同任务的另一种方法是使用[选项卡式窗格](../components/tabbedpane.html)。下图显示了上一个示例的选项卡式窗格版本：

![A snapshot of TabDemo](img/0da84c9eda881e73f8a254ae9ab6f61c.jpg)

由于选项卡式窗格提供了自己的 GUI，因此使用选项卡式窗格比使用`CardLayout`类更简单。例如，使用选项卡式窗格实现前面的示例会导致程序包含更少的代码行。

单击“启动”按钮以使用 [Java™Web Start](http://www.oracle.com/technetwork/java/javase/javawebstart/index.html) （[下载 JDK 7 或更高版本](http://www.oracle.com/technetwork/java/javase/downloads/index.html)）运行 TabDemo。或者，要自己编译并运行示例，请参考[示例索引](../examples/layout/index.html#TabDemo)。

[![Launches the TabDemo application](img/4707a69a17729d71c56b2bdbbb4cc61c.jpg)](https://docs.oracle.com/javase/tutorialJWS/samples/uiswing/TabDemoProject/TabDemo.jnlp)

该演示的完整代码位于 [`TabDemo.java`](../examples/layout/TabDemoProject/src/layout/TabDemo.java) 文件中。

从概念上讲，`CardLayout`管理的每个组件就像一个堆叠中的扑克牌或交易卡，其中只有顶部卡片随时可见。您可以选择以下列任何一种方式显示的卡片：

*   通过要求第一张或最后一张卡，按顺序将其添加到容器中
*   通过向后或向前翻转甲板
*   通过指定具有特定名称的卡

`CardLayoutDemo`类使用最后一个方案。

[`CardLayoutDemo.java`](../examples/layout/CardLayoutDemoProject/src/layout/CardLayoutDemo.java) 应用程序的以下代码片段创建`CardLayout`对象及其管理的组件。

```
//Where instance variables are declared:
JPanel cards;
final static String BUTTONPANEL = "Card with JButtons";
final static String TEXTPANEL = "Card with JTextField";

//Where the components controlled by the CardLayout are initialized:
//Create the "cards".
JPanel card1 = new JPanel();
...
JPanel card2 = new JPanel();
...

//Create the panel that contains the "cards".
cards = new JPanel(new CardLayout());
cards.add(card1, BUTTONPANEL);
cards.add(card2, TEXTPANEL);

```

要将组件添加到`CardLayout`对象管理的容器，请指定标识要添加的组件的字符串。例如，在此演示中，第一个面板具有字符串`"Card with JButtons"`，第二个面板具有字符串`"Card with JTextField"`。在此演示中，这些字符串也在组合框中使用。

要选择`CardLayout`对象显示的组件，请在代码示例中添加其他代码：

```
//Where the GUI is assembled:
//Put the JComboBox in a JPanel to get a nicer look.
JPanel comboBoxPane = new JPanel(); //use FlowLayout
String comboBoxItems[] = { BUTTONPANEL, TEXTPANEL };
JComboBox cb = new JComboBox(comboBoxItems);
cb.setEditable(false);
cb.addItemListener(this);
comboBoxPane.add(cb);
...
pane.add(comboBoxPane, BorderLayout.PAGE_START);
pane.add(cards, BorderLayout.CENTER);
...

//Method came from the ItemListener class implementation,
//contains functionality to process the combo box item selecting
public void itemStateChanged(ItemEvent evt) {
    CardLayout cl = (CardLayout)(cards.getLayout());
    cl.show(cards, (String)evt.getItem());
}

```

此示例显示要使用`CardLayout`类的`show`方法，必须设置当前可见的组件。 `show`方法中的第一个参数是`CardLayout`控制的容器 - 即`CardLayout`管理的组件的容器。第二个参数是标识要显示的组件的字符串。此字符串与将组件添加到容器时使用的字符串相同。

下表列出了用于选择组件的`CardLayout`类方法。对于每个方法，第一个参数是`CardLayout`是布局管理器的容器（`CardLayout`控制的卡的容器）。

| 方法 | 目的 |
| --- | --- |
| 首先 [`（容器 _ 父 _）`](https://docs.oracle.com/javase/8/docs/api/java/awt/CardLayout.html#first-java.awt.Container-) | 翻转到容器的第一张卡片。 |
| [`下一个（容器 _ 父 _）`](https://docs.oracle.com/javase/8/docs/api/java/awt/CardLayout.html#next-java.awt.Container-) | 翻转到容器的下一张卡片。如果当前可见的卡是最后一张，则此方法将翻转到布局中的第一张卡。 |
| [`previous（Container _parent_ ）`](https://docs.oracle.com/javase/8/docs/api/java/awt/CardLayout.html#previous-java.awt.Container-) | 翻转到容器的上一张卡片。如果当前可见的卡是第一张，则此方法将翻转到布局中的最后一张卡。 |
| [`最后（容器 _ 父 _）`](https://docs.oracle.com/javase/8/docs/api/java/awt/CardLayout.html#last-java.awt.Container-) | 翻转到容器的最后一张卡片。 |
| [`显示（容器 _ 父 _，字符串 _ 名称 _）`](https://docs.oracle.com/javase/8/docs/api/java/awt/CardLayout.html#show-java.awt.Container-java.lang.String-) | 使用 [`addLayoutComponent`](https://docs.oracle.com/javase/8/docs/api/java/awt/CardLayout.html#addLayoutComponent-java.awt.Component-java.lang.Object-) 方法翻转到使用指定的`name`添加到此布局的组件。 |

此路径中只有一个示例使用`CardLayout`，这是 [`CardLayoutDemo`](../examples/layout/index.html#CardLayoutDemo) 。通常，我们的示例使用[选项卡式窗格](../components/tabbedpane.html)而不是`CardLayout`，因为选项卡式窗格提供了自己的 GUI。