Documentation

The Java™ Tutorials
Hide TOC
How to Use Combo Boxes如何使用组合框
Trail: Creating a GUI With Swing
Lesson: Using Swing Components
Section: How to Use Various Components

How to Use Combo Boxes如何使用组合框

A JComboBox, which lets the user choose one of several choices, can have two very different forms. JComboBox允许用户从多个选项中选择一个,可以有两种非常不同的形式。The default form is the uneditable combo box, which features a button and a drop-down list of values. 默认形式是不可编辑的组合框,其中包含一个按钮和一个值下拉列表。The second form, called the editable combo box, features a text field with a small button abutting it. 第二种形式称为可编辑组合框,其特征是一个文本字段,旁边有一个小按钮。The user can type a value in the text field or click the button to display a drop-down list. 用户可以在文本字段中键入值或单击按钮以显示下拉列表。Here's what the two forms of combo boxes look like in the Java look and feel:以下是Java外观中两种形式的组合框的外观:

An uneditable combo box
An editable combo box
An uneditable combo box
An editable combo box
Uneditable combo box, before (top)不可编辑的组合框,在
and after the button is clicked点击按钮之前(顶部)和之后
Editable combo box, before and after可编辑组合框,在
the arrow button is clicked点击箭头按钮之前(顶部)和之后

Combo boxes require little screen space, and their editable (text field) form is useful for letting the user quickly choose a value without limiting the user to the displayed values. 组合框需要很少的屏幕空间,它们的可编辑(文本字段)形式有助于让用户快速选择值,而不会将用户限制为显示的值。Other components that can display one-of-many choices are groups of radio buttons and lists. 可以显示许多选项之一的其他组件是单选按钮组列表组Groups of radio buttons are generally the easiest for users to understand, but combo boxes can be more appropriate when space is limited or more than a few choices are available. 单选按钮组通常是用户最容易理解的,但当空间有限或有多个选项可用时,组合框可能更合适。Lists are not terribly attractive, but they're more appropriate than combo boxes when the number of items is large (say, over 20) or when selecting multiple items might be valid.列表不是很吸引人,但当项目数量很大(比如超过20个)或选择多个项目可能有效时,列表比组合框更合适。

Because editable and uneditable combo boxes are so different, this section treats them separately. 由于可编辑和不可编辑的组合框非常不同,因此本节将它们分开处理。This section covers these topics:本节涵盖以下主题:

Using an Uneditable Combo Box使用不可编辑的组合框

The application shown here uses an uneditable combo box for choosing a pet picture:此处显示的应用程序使用不可编辑的组合框来选择宠物图片:

An uneditable combo box


Try this: 
  1. Click the Launch button to run the ComboBox Demo using Java™ Web Start (download JDK 7 or later). 单击启动按钮,使用Java™Web启动运行组合框演示(下载JDK 7或更高版本)。Alternatively, to compile and run the example yourself, consult the example index.或者,要自己编译和运行示例,请参考示例索引Launches the ComboBoxDemo example

  2. Choose an animal name from the combo box to view its picture.从组合框中选择动物名称以查看其图片。
  3. Compare the operation and GUI of this program to one that uses radio buttons: run RadioButtonDemo (it requires release 6). 将此程序的操作和GUI与使用单选按钮的程序进行比较:运行RadioButtonDemo(它需要版本6)。You might want to compare the source code as well: ComboBoxDemo.java vs. RadioButtonDemo.java.您可能还需要比较源代码:ComboBoxDemo.java对比RadioButtonDemo.java

The following code, taken from ComboBoxDemo.java, creates an uneditable combo box and sets it up:以下代码取自ComboBoxDemo.java,创建了一个不可编辑的组合框并对其进行了设置:

String[] petStrings = { "Bird", "Cat", "Dog", "Rabbit", "Pig" };

//Create the combo box, select item at index 4.
//Indices start at 0, so 4 specifies the pig.
JComboBox petList = new JComboBox(petStrings);
petList.setSelectedIndex(4);
petList.addActionListener(this);

This combo box contains an array of strings, but you could just as easily use icons instead. 这个组合框包含一个字符串数组,但您也可以轻松地使用图标。To put anything else into a combo box or to customize how the items in a combo box look, you need to write a custom renderer. 要将任何其他内容放入组合框或自定义组合框中的项目的外观,您需要编写自定义渲染器。An editable combo box would also need a custom editor. 一个可编辑的组合框还需要一个自定义编辑器。Refer to Providing a Custom Renderer for information and an example.有关信息和示例,请参阅提供自定义渲染器

The preceding code registers an action listener on the combo box. 前面的代码在组合框上注册了一个动作侦听器。To see the action listener implementation and learn about other types of listeners supported by combo box, refer to Handling Events on a Combo Box.要查看动作侦听器实现并了解组合框支持的其他类型的侦听器,请参阅处理组合框上的事件

No matter which constructor you use, a combo box uses a combo box model to contain and manage the items in its menu. 无论使用哪个构造函数,组合框都使用组合框模型来包含和管理其菜单中的项目。When you initialize a combo box with an array or a vector, the combo box creates a default model object for you. 使用数组或向量初始化组合框时,组合框将为您创建默认模型对象。As with other Swing components, you can customize a combo box in part by implementing a custom model — an object that implements the ComboBoxModel interface. 与其他Swing组件一样,您可以通过实现自定义模型—实现ComboBoxModel接口的对象。 


Note: 

Be careful when implementing a custom model for a combo box. 为组合框实现自定义模型时要小心。The JComboBox methods that change the items in the combo box's menu, such as insertItemAt, work only if the data model implements the MutableComboBoxModel interface (a subinterface of ComboBoxModel). 只有当数据模型实现MutableComboBoxModel接口(Comboxmodel的子接口)时,更改组合框菜单中项目的JComboBox方法(如insertItemAt)才有效。Refer to the API tables to see which methods are affected.请参阅API表以了解哪些方法受到影响。

Something else to watch out for — even for uneditable combo boxes — is ensuring that your custom model fires list data events when the combo box's data or state changes. 还有什么需要注意的—即使对于不可编辑的组合框—确保自定义模型在组合框的数据或状态更改时触发列表数据事件Even immutable combo box models, whose data never changes, must fire a list data event (a CONTENTS_CHANGED event) when the selection changes. 即使是数据从不更改的不可变组合框模型,在选择更改时也必须触发列表数据事件(CONTENTS_CHANGED事件)。One way to get the list data event firing code for free is to make your combo box model a subclass of AbstractListModel.免费获取列表数据事件触发代码的一种方法是使组合框模型成为AbstractListModel的子类。


Handling Events on a Combo Box处理组合框上的事件

Here's the code from ComboBoxDemo.java that registers and implements an action listener on the combo box:下面是ComboBoxDemo.java中的代码,它在组合框上注册并实现了一个动作监听器:

public class ComboBoxDemo ... implements ActionListener {
    . . .
        petList.addActionListener(this) {
    . . .
    public void actionPerformed(ActionEvent e) {
        JComboBox cb = (JComboBox)e.getSource();
        String petName = (String)cb.getSelectedItem();
        updateLabel(petName);
    }
    . . .
}

This action listener gets the newly selected item from the combo box, uses it to compute the name of an image file, and updates a label to display the image. 此操作侦听器从组合框中获取新选择的项,使用它计算图像文件的名称,并更新标签以显示图像。The combo box fires an action event when the user selects an item from the combo box's menu. 当用户从组合框的菜单中选择一个项目时,组合框触发一个动作事件。See How to Write an Action Listener, for general information about implementing action listeners.有关实现动作侦听器的一般信息,请参阅如何编写动作侦听器

Combo boxes also generate item events, which are fired when any of the items' selection state changes. 组合框还生成项目事件,当任何项目的选择状态发生变化时将触发这些事件。Only one item at a time can be selected in a combo box, so when the user makes a new selection the previously selected item becomes unselected. 在组合框中一次只能选择一个项目,因此当用户进行新选择时,先前选择的项目将变为未选中。Thus two item events are fired each time the user selects a different item from the menu. 因此,每当用户从菜单中选择不同的项目时,触发两个项目事件。If the user chooses the same item, no item events are fired. 如果用户选择同一项,则不会触发任何项事件。Use addItemListener to register an item listener on a combo box. 使用addItemListener在组合框上注册项侦听器。How to Write an Item Listener如何编写项目侦听器 gives general information about implementing item listeners.提供有关实现项侦听器的一般信息。

Although JComboBox inherits methods to register listeners for low-level events — focus, key, and mouse events, for example — we recommend that you don't listen for low-level events on a combo box. 尽管JComboBox继承了为低级事件注册侦听器的方法;焦点、按键和鼠标事件,例如—我们建议您不要在组合框上侦听低级事件。Here's why: A combo box is a compound component — it is comprised of two or more other components. 原因如下:组合框是一个复合组件—它由两个或多个其他部件组成。The combo box itself fires high-level events such as action events. 组合框本身触发高级事件,如动作事件。Its subcomponents fire low-level events such as mouse, key, and focus events. 其子组件触发低级事件,如鼠标、按键和焦点事件。The low-level events and the subcomponent that fires them are look-and-feel-dependent. 低级事件和触发它们的子组件是外观相关的。To avoid writing look-and-feel-dependent code, you should listen only for high-level events on a compound component such as a combo box. 为了避免编写外观相关的代码,您应该只侦听复合组件(如组合框)上的高级事件。For information about events, including a discussion about high- and low-level events, refer to Writing Event Listeners.有关事件的信息,包括有关高级和低级事件的讨论,请参阅编写事件侦听器

Using an Editable Combo Box使用可编辑组合框

Here's a picture of a demo application that uses an editable combo box to enter a pattern with which to format dates.这是一个演示应用程序的图片,它使用一个可编辑的组合框来输入格式化日期的模式。

An editable combo box

Try this: 
  1. Click the Launch button to run the ComboBox2 Demo using Java™ Web Start (download JDK 7 or later). 单击启动按钮,使用Java™Web启动运行ComboBox2演示(下载JDK 7或更高版本)。Alternatively, to compile and run the example yourself, consult the example index.或者,要自己编译和运行示例,请参考示例索引Launches the ComboBoxDemo2 example

  2. Enter a new pattern by choosing one from the combo box's menu. 通过从组合框的菜单中选择一个模式来输入新模式。The program reformats the current date and time.程序将重新格式化当前日期和时间。
  3. Enter a new pattern by typing one in and pressing Enter. 通过在中键入一个图案并按Enter键输入新图案。Again the program reformats the current date and time.程序再次重新格式化当前日期和时间。

The following code, taken from ComboBoxDemo2.java, creates and sets up the combo box:以下代码取自ComboBoxDemo2.java,用于创建和设置组合框:

String[] patternExamples = {
         "dd MMMMM yyyy",
         "dd.MM.yy",
         "MM/dd/yy",
         "yyyy.MM.dd G 'at' hh:mm:ss z",
         "EEE, MMM d, ''yy",
         "h:mm a",
         "H:mm:ss:SSS",
         "K:mm a,z",
         "yyyy.MMMMM.dd GGG hh:mm aaa"
};
. . .
JComboBox patternList = new JComboBox(patternExamples);
patternList.setEditable(true);
patternList.addActionListener(this);

This code is very similar to the previous example, but warrants a few words of explanation. 此代码与前面的示例非常相似,但需要几句解释。The bold line of code explicitly turns on editing to allow the user to type values in. 粗体代码行显式打开编辑,允许用户键入值。This is necessary because, by default, a combo box is not editable. 这是必要的,因为默认情况下,组合框是不可编辑的。This particular example allows editing on the combo box because its menu does not provide all possible date formatting patterns, just shortcuts to frequently used patterns.这个特定的示例允许在组合框上进行编辑,因为它的菜单不提供所有可能的日期格式模式,只提供常用模式的快捷方式。

An editable combo box fires an action event when the user chooses an item from the menu and when the user types Enter. 当用户从菜单中选择一个项目时,当用户键入Enter时,可编辑组合框将触发一个动作事件。Note that the menu remains unchanged when the user enters a value into the combo box. 请注意,当用户在组合框中输入值时,菜单保持不变。If you want, you can easily write an action listener that adds a new item to the combo box's menu each time the user types in a unique value.如果需要,您可以很容易地编写一个动作监听器,每当用户键入一个唯一值时,该监听器会将一个新项添加到组合框的菜单中。

See Internationalization to learn more about formatting dates and other types of data.有关格式化日期和其他类型数据的详细信息,请参阅国际化

Providing a Custom Renderer提供自定义渲染器

A combo box uses a renderer to display each item in its menu. 组合框使用渲染器显示菜单中的每个项。If the combo box is uneditable, it also uses the renderer to display the currently selected item. 如果组合框不可编辑,它还使用渲染器显示当前选定的项目。An editable combo box, on the other hand, uses an editor to display the selected item. 另一方面,可编辑组合框使用编辑器来显示所选项目。A renderer for a combo box must implement the ListCellRenderer interface. 组合框的渲染器必须实现ListCellRenderer接口。A combo box's editor must implement ComboBoxEditor. ComboBoxEditor必须实现组合框编辑器。This section shows how to provide a custom renderer for an uneditable combo box.本节介绍如何为不可编辑的组合框提供自定义呈现器。

The default renderer knows how to render strings and icons. 默认渲染器知道如何渲染字符串和图标。If you put other objects in a combo box, the default renderer calls the toString method to provide a string to display. 如果将其他对象放在组合框中,默认呈现器将调用toString方法以提供要显示的字符串。You can customize the way a combo box renders itself and its items by implementing your own ListCellRenderer.通过实现自己的ListCellRenderer,可以自定义组合框自身及其项的呈现方式。

Here's a picture of an application that uses a combo box with a custom renderer:下面是一个使用带有自定义渲染器的组合框的应用程序的图片:

A combo box with a custom renderer

Click the Launch button to run the CustomComboBox Demo using Java™ Web Start (download JDK 7 or later). 单击启动按钮,使用Java™Web启动运行CustomComboBox演示(下载JDK 7或更高版本)。Alternatively, to compile and run the example yourself, consult the example index.或者,要自己编译和运行示例,请参考示例索引

Launches the CustomComboBoxDemo example

The full source code for this example is in CustomComboBoxDemo.java. 本示例的完整源代码位于CustomComboBoxDemo.java中。To get the image files it requires, consult the example index.要获取所需的图像文件,请参考示例索引

The following statements from the example create an instance of ComboBoxRenderer (a custom class) and set up the instance as the combo box's renderer:示例中的以下语句创建ComboBoxRenderer(一个自定义类)的实例,并将该实例设置为ComboxRender

JComboBox petList = new JComboBox(intArray);
. . .
ComboBoxRenderer renderer = new ComboBoxRenderer();
renderer.setPreferredSize(new Dimension(200, 130));
petList.setRenderer(renderer);
petList.setMaximumRowCount(3);

The last line sets the combo box's maximum row count, which determines the number of items visible when the menu is displayed. 最后一行设置组合框的最大行数,该行数确定显示菜单时可见的项目数。If the number of items in the combo box is larger than its maximum row count, the menu has a scroll bar. 如果组合框中的项目数大于其最大行数,则菜单具有滚动条。The icons are pretty big for a menu, so our code limits the number of rows to 3. 图标对于菜单来说相当大,因此代码将行数限制为3。Here's the implementation of ComboBoxRenderer, a renderer that puts an icon and text side-by-side:下面是ComboBoxRenderer的实现,一个将图标和文本并排放置的渲染器:

class ComboBoxRenderer extends JLabel
                       implements ListCellRenderer {
    . . .
    public ComboBoxRenderer() {
        setOpaque(true);
        setHorizontalAlignment(CENTER);
        setVerticalAlignment(CENTER);
    }

    /*
     * This method finds the image and text corresponding
     * to the selected value and returns the label, set up
     * to display the text and image.
     */
    public Component getListCellRendererComponent(
                                       JList list,
                                       Object value,
                                       int index,
                                       boolean isSelected,
                                       boolean cellHasFocus) {
        //Get the selected index. (The index parameter isn't
        //always valid, so just use the value.)
        int selectedIndex = ((Integer)value).intValue();

        if (isSelected) {
            setBackground(list.getSelectionBackground());
            setForeground(list.getSelectionForeground());
        } else {
            setBackground(list.getBackground());
            setForeground(list.getForeground());
        }

        //Set the icon and text.  If icon was null, say so.
        ImageIcon icon = images[selectedIndex];
        String pet = petStrings[selectedIndex];
        setIcon(icon);
        if (icon != null) {
            setText(pet);
            setFont(list.getFont());
        } else {
            setUhOhText(pet + " (no image available)",
                        list.getFont());
        }

        return this;
    }
    . . .
}

As a ListCellRenderer, ComboBoxRenderer implements a method called getListCellRendererComponent, which returns a component whose paintComponent method is used to display the combo box and each of its items. 作为ListCellRendererComboBoxRenderer实现了一个名为getListCellRendererComponent的方法,该方法返回一个组件,该组件的paintComponent方法用于显示组合框及其每个项。The easiest way to display an image and an icon is to use a label. 显示图像和图标的最简单方法是使用标签。So ComboBoxRenderer is a subclass of label and returns itself. 所以ComboBoxRenderer是label的子类,并返回自身。The implementation of getListCellRendererComponent configures the renderer to display the currently selected icon and its description.GetListCellRenderComponent的实现将渲染器配置为显示当前选定的图标及其描述。

These arguments are passed to getListCellRendererComponent:这些参数传递给getListCellRendererComponent

Note that combo boxes and lists use the same type of renderer — ListCellRenderer. 注意,组合框和列表使用相同类型的渲染器—ListCellRendererYou can save yourself some time by sharing renderers between combo boxes and lists, if it makes sense for your program.如果对您的程序有意义,您可以通过在组合框和列表之间共享渲染器来节省一些时间。

The Combo Box API组合框API

The following tables list the commonly used JComboBox constructors and methods. 下表列出了常用的JComboBox构造函数和方法。Other methods you are most likely to invoke on a JComboBox object are those it inherits from its superclasses, such as setPreferredSize. 您最有可能在JComboBox对象上调用的其他方法是从其超类继承的方法,例如setPreferredSizeSee The JComponent API for tables of commonly used inherited methods.有关常用继承方法的表,请参阅JComponent API

The API for using combo boxes falls into two categories:使用组合框的API分为两类:

Setting or Getting the Items in the Combo Boxes's Menu设置或获取组合框菜单中的项目
Method方法 Purpose目的
JComboBox()
JComboBox(ComboBoxModel)
JComboBox(Object[])
JComboBox(Vector)
Create a combo box with the specified items in its menu. 使用菜单中的指定项创建组合框。A combo box created with the default constructor has no items in the menu initially. 使用默认构造函数创建的组合框最初在菜单中没有项。Each of the other constructors initializes the menu from its argument: a model object, an array of objects, or a Vector of objects.其他每个构造函数从其参数初始化菜单:模型对象、对象数组或对象的Vector
void addItem(Object)
void insertItemAt(Object, int)
Add or insert the specified object into the combo box's menu. 将指定的对象添加或插入到组合框的菜单中。The insert method places the specified object at the specified index, thus inserting it before the object currently at that index. insert方法将指定对象放置在指定索引处,从而将其插入到当前位于该索引处的对象之前。These methods require that the combo box's data model be an instance of MutableComboBoxModel.这些方法要求组合框的数据模型是MutableComboxModel的实例。
Object getItemAt(int)
Object getSelectedItem()
Get an item from the combo box's menu.从组合框的菜单中获取项目。
void removeAllItems()
void removeItemAt(int)
void removeItem(Object)
Remove one or more items from the combo box's menu. 从组合框的菜单中删除一个或多个项目。These methods require that the combo box's data model be an instance of MutableComboBoxModel.这些方法要求组合框的数据模型是MutableComboxModel的实例。
int getItemCount() Get the number of items in the combo box's menu.获取组合框菜单中的项目数。
void setModel(ComboBoxModel)
ComboBoxModel getModel()
Set or get the data model that provides the items in the combo box's menu.设置或获取在组合框菜单中提供项目的数据模型。
void setAction(Action)
Action getAction()
Set or get the Action associated with the combo box. 设置或获取与组合框关联的ActionFor further information, see How to Use Actions.有关详细信息,请参阅如何使用操作
Customizing the Combo Box's Operation自定义组合框的操作
Method or Constructor方法或构造函数 Purpose目的
void addActionListener(ActionListener) Add an action listener to the combo box. 将操作侦听器添加到组合框中。The listener's actionPerformed method is called when the user selects an item from the combo box's menu or, in an editable combo box, when the user presses Enter.当用户从组合框的菜单中选择项目时,或者在可编辑的组合框中,当用户按Enter键时,将调用侦听器的actionPerformed方法。
void addItemListener(ItemListener) Add an item listener to the combo box. 将项目侦听器添加到组合框中。The listener's itemStateChanged method is called when the selection state of any of the combo box's items change.当组合框中任何项的选择状态更改时,将调用侦听器的itemStateChanged方法。
void setEditable(boolean)
boolean isEditable()
Set or get whether the user can type in the combo box.设置或获取用户是否可以在组合框中键入。
void setRenderer(ListCellRenderer)
ListCellRenderer getRenderer()
Set or get the object responsible for painting the selected item in the combo box. 设置或获取负责在组合框中绘制选定项目的对象。The renderer is used only when the combo box is uneditable. 渲染器仅在组合框不可编辑时使用。If the combo box is editable, the editor is used to paint the selected item instead.如果组合框是可编辑的,则编辑器将用于绘制选定项。
void setEditor(ComboBoxEditor)
ComboBoxEditor getEditor()
Set or get the object responsible for painting and editing the selected item in the combo box. 设置或获取负责在组合框中绘制和编辑选定项目的对象。The editor is used only when the combo box is editable. 该编辑器仅在组合框可编辑时使用。If the combo box is uneditable, the renderer is used to paint the selected item instead.如果组合框不可编辑,则使用渲染器绘制选定项。

Examples that Use Combo Boxes使用组合框的示例

This table shows the examples that use JComboBox and where those examples are described.下表显示了使用JComboBox的示例以及这些示例的描述位置。

Example示例 Where Described描述位置 Notes备注
ComboBoxDemo This section本节 Uses an uneditable combo box.使用不可编辑的组合框。
ComboBoxDemo2 This section本节 Uses an editable combo box.使用可编辑的组合框。
CustomComboBoxDemo This section本节 Provides a custom renderer for a combo box.为组合框提供自定义呈现器。
TableRenderDemo How to Use Tables (Using a Combo Box as an Editor)如何使用表格(使用组合框作为编辑器 Shows how to use a combo box as a table cell editor.演示如何将组合框用作表单元格编辑器。

Previous page: How to Use Color Choosers
Next page: How to Make Dialogs