本教程是针对 JDK 8 编写的。本页面描述的示例和实践不利用后续版本中引入的改进,可能使用不再可用的技术。
请参阅 Java 语言变化,了解 Java SE 9 及后续版本中更新的语言特性的概述。
请参阅 JDK 发行说明,了解所有 JDK 发布版本的新功能、增强功能以及已删除或不推荐使用的选项的信息。
一个JComboBox
,它允许用户从多个选择中选择一个,可以有两种非常不同的形式。默认形式是不可编辑的组合框,它包括一个按钮和一个下拉值列表。第二种形式称为可编辑的组合框,它包括一个与之相邻的文本字段和一个小按钮。用户可以在文本字段中输入一个值,或者点击按钮显示一个下拉列表。以下是Java外观下这两种组合框的样式:
|
|
|
|
不可编辑的组合框,点击按钮之前(上方) 和之后 |
可编辑的组合框,点击箭头按钮之前和之后 |
组合框占用很少的屏幕空间,它们的可编辑(文本字段)形式对于让用户快速选择一个值而不限制用户只能选择显示的值非常有用。其他可以显示多个选择之一的组件包括一组单选按钮和列表。一组单选按钮通常对用户来说最容易理解,但是当空间有限或者有多个选择可用时,组合框可能更合适。列表并不太吸引人,但当项目数量较大(比如超过20个)或者需要选择多个项目时,它们比组合框更合适。
由于可编辑和不可编辑的组合框非常不同,本节将分别介绍它们。本节包括以下主题:
这里展示的应用程序使用不可编辑的组合框来选择宠物图片:
ComboBoxDemo.java
vs. RadioButtonDemo.java
。以下代码取自ComboBoxDemo.java
,创建了一个不可编辑的组合框并进行设置:
String[] petStrings = { "鸟", "猫", "狗", "兔子", "猪" }; //创建一个下拉列表框,并选择索引为4的项。 //索引从0开始,所以4表示猪。 JComboBox petList = new JComboBox(petStrings); petList.setSelectedIndex(4); petList.addActionListener(this);
这个下拉列表框包含一个字符串数组,但你也可以使用图标。如果要将其他内容放入下拉列表框,或者自定义下拉列表框中的项的外观,你需要编写一个自定义渲染器。一个可编辑的下拉列表框还需要一个自定义编辑器。请参考提供自定义渲染器的信息和示例。
上述代码在下拉列表框上注册了一个动作监听器。要查看动作监听器的实现以及下拉列表框支持的其他类型的监听器,请参考处理下拉列表框上的事件。
无论使用哪个构造函数,下拉列表框都使用一个下拉列表框模型来包含和管理其菜单中的项。当你使用数组或向量初始化下拉列表框时,下拉列表框会为你创建一个默认的模型对象。与其他 Swing 组件一样,你可以通过实现一个自定义模型(实现ComboBoxModel
接口的对象)来部分自定义下拉列表框。
当为下拉列表框实现自定义模型时要小心。仅当数据模型实现了MutableComboBoxModel
接口(ComboBoxModel
的子接口)时,JComboBox
中更改菜单中的项的方法,如insertItemAt
,才能正常工作。请参考API表格以查看受影响的方法。
还有一点需要注意,即使对于不可编辑的下拉列表框,也要确保在下拉列表框的数据或状态发生更改时,你的自定义模型能够触发列表数据事件。即使是数据从不改变的不可变下拉列表框模型,在选择更改时也必须触发列表数据事件(一个CONTENTS_CHANGED
事件)。获取列表数据事件触发代码的一种简单方法是将你的下拉列表框模型作为AbstractListModel
的子类。
下面是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); } . . . }
这个动作监听器从组合框中获取新选择的项,使用它来计算图像文件的名称,并更新标签以显示图像。当用户从组合框的菜单中选择一个项时,组合框会触发一个动作事件。有关实现动作监听器的常规信息,请参阅如何编写动作监听器。
组合框还会生成项目事件,当任何项的选择状态发生变化时会触发这些事件。在组合框中一次只能选择一个项,所以当用户进行新选择时,先前选择的项将被取消选择。因此,每当用户从菜单中选择一个不同的项时,会触发两个项目事件。如果用户选择相同的项,则不会触发项目事件。使用addItemListener
在组合框上注册项目监听器。如何编写项目监听器提供了有关实现项目监听器的常规信息。
虽然JComboBox
继承了用于注册低级事件的方法,如焦点、键盘和鼠标事件,但我们建议您不要在组合框上监听低级事件。原因如下:组合框是一个复合组件,它由两个或多个其他组件组成。组合框本身会触发高级事件,如动作事件。它的子组件会触发低级事件,如鼠标、键盘和焦点事件。低级事件和触发它们的子组件与外观和感觉有关。为了避免编写与外观和感觉有关的代码,您应该只在复合组件(如组合框)上监听高级事件。有关事件的信息,包括关于高级和低级事件的讨论,请参阅编写事件监听器。
下面是一个使用可编辑的组合框输入日期格式的演示应用程序的图片。
以下代码取自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);
这段代码与之前的示例非常相似,但需要解释一下。代码中加粗的那一行显式地启用了编辑功能,允许用户输入值。这是必需的,因为默认情况下,组合框是不可编辑的。这个特定的示例允许在组合框中进行编辑,因为其菜单不提供所有可能的日期格式化模式,只提供常用模式的快捷方式。
可编辑的组合框在用户从菜单中选择一个项或者用户输入回车键时触发动作事件。请注意,当用户在组合框中输入值时,菜单不会改变。如果需要,你可以很容易地编写一个动作监听器,每当用户输入一个唯一的值时,就向组合框的菜单中添加一个新项。
请参阅国际化了解更多关于日期和其他类型数据格式化的内容。
组合框使用一个渲染器来显示菜单中的每个项。如果组合框不可编辑,它还使用渲染器来显示当前选择的项。而可编辑的组合框则使用一个编辑器来显示选中的项。组合框的渲染器必须实现ListCellRenderer
接口。组合框的编辑器必须实现ComboBoxEditor
。本节展示如何为不可编辑的组合框提供自定义渲染器。
默认的渲染器知道如何渲染字符串和图标。如果你将其他对象放入组合框中,默认的渲染器会调用toString
方法来提供要显示的字符串。你可以通过实现自己的ListCellRenderer
来自定义组合框及其项的渲染方式。
下面是一个使用自定义渲染器的应用程序截图:
点击“启动”按钮以使用Java™ Web Start运行CustomComboBox演示(下载JDK 7或更高版本)。或者,如果要自行编译和运行示例,请参考示例索引。
此示例的完整源代码位于CustomComboBoxDemo.java
中。要获取它所需的图像文件,请参考示例索引。
以下代码片段在示例中创建了一个ComboBoxRenderer
实例(一个自定义类),并将该实例设置为组合框的渲染器:
JComboBox petList = new JComboBox(intArray); . . . ComboBoxRenderer renderer = new ComboBoxRenderer(); renderer.setPreferredSize(new Dimension(200, 130)); petList.setRenderer(renderer); petList.setMaximumRowCount(3);
最后一行设置了组合框的最大行数,该行数确定了菜单显示时可见的项目数。如果组合框中的项目数量大于其最大行数,则菜单会出现滚动条。由于图标在菜单中相对较大,所以我们的代码将行数限制为3。下面是ComboBoxRenderer
的实现,它将图标和文本并排显示:
class ComboBoxRenderer extends JLabel implements ListCellRenderer { . . . public ComboBoxRenderer() { setOpaque(true); setHorizontalAlignment(CENTER); setVerticalAlignment(CENTER); } /* * 此方法找到与所选值对应的图像和文本,并返回设置好的标签以显示文本和图像。 */ public Component getListCellRendererComponent( JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { //获取所选索引。(index参数不总是有效的,所以只使用value。) int selectedIndex = ((Integer)value).intValue(); if (isSelected) { setBackground(list.getSelectionBackground()); setForeground(list.getSelectionForeground()); } else { setBackground(list.getBackground()); setForeground(list.getForeground()); } //设置图标和文本。如果图标为空,则显示提示信息。 ImageIcon icon = images[selectedIndex]; String pet = petStrings[selectedIndex]; setIcon(icon); if (icon != null) { setText(pet); setFont(list.getFont()); } else { setUhOhText(pet + "(无可用图像)", list.getFont()); } return this; } . . . }
作为 ListCellRenderer
,ComboBoxRenderer
实现了一个名为 getListCellRendererComponent
的方法,该方法返回一个组件,其 paintComponent
方法用于显示组合框及其每个项目。显示图像和图标的最简单方法是使用标签。所以 ComboBoxRenderer
是标签的子类,并返回自身。 getListCellRendererComponent
的实现配置了渲染器以显示当前选定的图标及其描述。
以下参数将传递给 getListCellRendererComponent
:
JList list
— 用于在后台显示项目的列表对象。该示例使用此对象的颜色设置前景色和背景色。Object value
— 要呈现的对象。在此示例中为一个 Integer
。int index
— 要呈现的对象的索引。boolean isSelected
— 表示要呈现的对象是否被选中。示例中用于确定使用哪些颜色。boolean cellHasFocus
— 表示要呈现的对象是否具有焦点。请注意,组合框和 列表 使用相同类型的渲染器 — ListCellRenderer
。如果在您的程序中有意义,您可以通过在组合框和列表之间共享渲染器来节省时间。
以下表列出了常用的 JComboBox
构造函数和方法。您最有可能在 JComboBox
对象上调用的其他方法是从其超类继承的方法,例如 setPreferredSize
。有关常用继承方法的表,请参见 JComponent API。
使用组合框的 API 可分为两类:
设置或获取组合框菜单中的项目JComboBox()Vector
void addItem(Object)
MutableComboBoxModel
Object getItemAt(int)
MutableComboBoxModel
int getItemCount()void setModel(ComboBoxModel)
Action
如何使用动作
方法或构造函数 | 目的 |
---|---|
void addActionListener(ActionListener) | 向组合框添加一个动作监听器。当用户从组合框的菜单中选择一个项目或在可编辑的组合框中按下Enter键时,会调用监听器的actionPerformed 方法。 |
void addItemListener(ItemListener) | 向组合框添加一个项目监听器。当组合框的任何项目的选择状态发生改变时,会调用监听器的itemStateChanged 方法。 |
void setEditable(boolean) boolean isEditable() |
设置或获取用户是否可以在组合框中输入内容。 |
void setRenderer(ListCellRenderer) ListCellRenderer getRenderer() |
设置或获取负责在组合框中绘制选定项目的对象。渲染器仅在组合框不可编辑时使用。如果组合框可编辑,则使用编辑器来绘制选定的项目。 |
void setEditor(ComboBoxEditor) ComboBoxEditor getEditor() |
设置或获取负责在组合框中绘制和编辑选定项目的对象。编辑器仅在组合框可编辑时使用。如果组合框不可编辑,则使用渲染器来绘制选定的项目。 |
此表格显示了使用 JComboBox
的示例以及这些示例所在的位置。
示例 | 所在位置 | 说明 |
---|---|---|
ComboBoxDemo |
本节 | 使用不可编辑的组合框。 |
ComboBoxDemo2 |
本节 | 使用可编辑的组合框。 |
CustomComboBoxDemo |
本节 | 为组合框提供自定义渲染器。 |
TableRenderDemo |
如何使用表格(将组合框用作编辑器) | 演示了如何将组合框用作表格单元格编辑器。 |