如何使用清单
JList为用户提供一组项目,以一列或多列显示,供您选择。列表中可以包含许多项,因此它们通常放在scroll panes中。
除了列表之外,以下 Swing 组件还向用户显示多个可选项目:combo boxes,menus,tables以及check boxes或radio buttons组。要显示分层数据,请使用tree。
下图显示了两个使用列表的应用程序。本节将这些示例用作后续讨论的基础。
ListDialog | |
(由 ListDialogRunner 使用) | ListDemo |
Try this:
-
单击启动按钮以使用Java™Web 开始(下载 JDK 7 或更高版本)运行 ListDemo。另外,要自己编译和运行示例,请查阅example index。
-
单击启动按钮以运行 ListDialogRunner。或者,要自己编译和运行示例,请查阅example index。
-
要弹出 ListDialog,请在“命名那个婴儿”窗口中单击“选择新名称...”按钮。
出现的对话框是一个 ListDialog 实例,该实例已被自定义为具有标题 Name Chooser。 -
在 ListDemo 中,try添加(雇用)和删除(射击)一些物品。
本节的其余部分讨论以下主题:
创建模型
有三种创建列表模型的方法:
-
DefaultListModel-一切都已为您完成。此页面中的示例使用
DefaultListModel
。 -
AbstractListModel —您可以 管理 数据并调用“触发”方法。对于这种方法,必须子类
AbstractListModel
并实现从ListModel
interface继承的getSize
和getElementAt
方法。 -
ListModel-您可以 管理 所有事务。
初始化列表
这是来自ListDialog.java的代码,用于创建并设置其列表:
list = new JList(data); //data has type Object[]
list.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
list.setLayoutOrientation(JList.HORIZONTAL_WRAP);
list.setVisibleRowCount(-1);
...
JScrollPane listScroller = new JScrollPane(list);
listScroller.setPreferredSize(new Dimension(250, 80));
代码将数组传递给列表的构造函数。数组中填充了从另一个对象传入的字符串。在我们的示例中,字符串 恰好是男孩的名字。
其他JList
构造函数使您可以从Vector
或遵循ListModelinterface的对象初始化列表。如果使用数组或向量初始化列表,则构造函数将隐式创建默认列表模型。默认列表模型是不可变的-您不能添加,删除或替换列表中的项目。要创建可以单独更改其项 Object 列表,请将列表的模型设置为可变列表模型类的实例,例如DefaultListModel的实例。您可以在创建列表时或通过调用setModel
方法来设置列表的模型。有关示例,请参见向列表添加项目和从列表中删除项目。
setSelectionMode
的调用指定了用户可以选择多少个项目,以及它们是否必须是连续的。下一节将向您详细介绍选择 Pattern。
调用setLayoutOrientation
可使列表在多列中显示其数据。值JList.HORIZONTAL_WRAP
指定列表在换行到新行之前应从左至右显示其项目。另一个可能的值是JList.VERTICAL_WRAP
,它指定在包装到新列之前从上至下(通常)显示数据。下图显示了这两种包装方式以及默认值JList.VERTICAL
。
HORIZONTAL_WRAP | VERTICAL_WRAP | VERTICAL |
结合对setLayoutOrientation
的调用,调用setVisibleRowCount(-1)
可使列表在屏幕上的可用空间中显示最大数量的项目。 setVisibleRowCount
的另一个常见用法是在列表的滚动窗格中指定列表希望显示多少行。
选择列表中的项目
列表使用ListSelectionModel的实例来 管理 其选择。默认情况下,列表选择模型允许一次选择项 Object 任何组合。您可以通过调用列表上的setSelectionMode
方法来指定其他选择 Pattern。例如,ListDialog
和ListDemo
都将选择 Pattern 设置为SINGLE_SELECTION
(由ListSelectionModel
定义的常数),以便只能选择列表中的一项。下表描述了三种列表选择 Pattern:
Mode | Description |
---|---|
SINGLE_SELECTION | |
一次只能选择一项。当用户选择一个项目时,首先取消选择任何先前选择的项目。 | |
SINGLE_INTERVAL_SELECTION | 可以选择多个连续的项目。当用户开始新的选择范围时,首先取消选择任何先前选择的项目。 |
MULTIPLE_INTERVAL_SELECTION | 默认值。可以选择任何项目组合。用户必须明确取消选择项目。 |
无论您的列表使用哪种选择 Pattern,只要选择更改,列表都会触发列表选择事件。您可以使用addListSelectionListener
方法将列表选择监听器添加到列表中来处理这些事件。列表选择侦听器必须实现一个方法:valueChanged
。这是ListDemo
中侦听器的valueChanged
方法:
public void valueChanged(ListSelectionEvent e) {
if (e.getValueIsAdjusting() == false) {
if (list.getSelectedIndex() == -1) {
//No selection, disable fire button.
fireButton.setEnabled(false);
} else {
//Selection, enable the fire button.
fireButton.setEnabled(true);
}
}
}
可以从单个用户操作(例如单击鼠标)生成许多列表选择事件。如果用户仍在操纵选择,则getValueIsAdjusting
方法返回true
。该特定程序仅对用户操作的final结果感兴趣,因此valueChanged
方法仅在getValueIsAdjusting
返回false
时才执行某些操作。
由于列表处于单选 Pattern,因此此代码可以使用getSelectedIndex
获取刚刚选择的项 Object 索引。当选择 Pattern 允许选择多个项目时,JList
为设置或获取选择提供其他方法。如果需要,您可以侦听列表的列表选择模型上的事件,而不是列表本身。 ListSelectionDemo是一个示例,显示了如何在列表选择模型上侦听列表选择事件,并允许您动态更改列表的选择 Pattern。
向列表添加项目和从列表中删除项目
我们之前显示的 ListDemo 示例具有一个列表,其内容可以更改。您可以在ListDemo.java中找到 ListDemo 的源代码。这是 ListDemo 代码,它创建一个可变的列表模型对象,将初始项放入其中,并使用列表模型创建列表:
listModel = new DefaultListModel();
listModel.addElement("Jane Doe");
listModel.addElement("John Smith");
listModel.addElement("Kathy Green");
list = new JList(listModel);
该特定程序使用DefaultListModel
的实例,该实例是 Swing 提供的类。尽管有类名,但列表中没有DefaultListModel
,除非您的程序明确指定了它。如果DefaultListModel
不满足您的需求,则可以编写一个自定义列表模型,该模型必须遵守ListModel
interface。
以下代码段显示了在 Fire 按钮上注册的动作侦听器的actionPerformed
方法。粗体代码行将删除列表中的选定项目。如果列表现在为空,则方法中的其余行将禁用“启动”按钮,如果列表为空,则进行另一选择。
public void actionPerformed(ActionEvent e) {
int index = list.getSelectedIndex();
listModel.remove(index);
int size = listModel.getSize();
if (size == 0) { //Nobody's left, disable firing.
fireButton.setEnabled(false);
} else { //Select an index.
if (index == listModel.getSize()) {
//removed item in last position
index--;
}
list.setSelectedIndex(index);
list.ensureIndexIsVisible(index);
}
}
这是 Hire 按钮和文本字段共享的操作侦听器的actionPerformed
方法:
public void actionPerformed(ActionEvent e) {
String name = employeeName.getText();
//User did not type in a unique name...
if (name.equals("") || alreadyInList(name)) {
Toolkit.getDefaultToolkit().beep();
employeeName.requestFocusInWindow();
employeeName.selectAll();
return;
}
int index = list.getSelectedIndex(); //get selected index
if (index == -1) { //no selection, so insert at beginning
index = 0;
} else { //add after the selected item
index++;
}
listModel.insertElementAt(employeeName.getText(), index);
//Reset the text field.
employeeName.requestFocusInWindow();
employeeName.setText("");
//Select the new item and make it visible.
list.setSelectedIndex(index);
list.ensureIndexIsVisible(index);
}
此代码使用列表模型的insertElementAt
方法在当前选择项之后(如果不存在选择项的话)在列表的开头插入新名称。如果您只想添加到列表的末尾,则可以使用DefaultListModel
的addElement
方法。
每当将项目添加到列表中,从列表中删除或在列表中进行修改时,列表模型都会触发列表数据事件。有关监听这些事件的信息,请参阅如何编写列表数据侦听器。该部分包含一个类似于ListDemo
的示例,但添加了用于在列表中向上或向下移动项 Object 按钮。
编写自定义单元格渲染器
列表使用称为单元格渲染器的对象来显示其每个项目。默认的单元格渲染器知道如何显示字符串 和图标,并通过调用toString
来显示Object
。如果要更改默认渲染器显示图标或字符串 的方式,或者想要与toString
提供的行为不同的行为,则可以实现自定义单元格渲染器。请按照以下步骤为列表提供自定义单元格渲染器:
-
编写一个实现ListCellRendererinterface的类。
-
创建您的类的实例,并使用该实例作为参数调用列表的
setCellRenderer
。
我们没有提供带有自定义单元格渲染器的列表示例,但是我们提供了带有自定义渲染器的组合框示例-组合框使用与列表相同类型的渲染器。请参阅提供自定义渲染器中描述的示例。
List API
下表列出了常用的JList
构造函数和方法。您最有可能在JList
对象上调用的其他方法是其超类提供的诸如setPreferredSize
之类的方法。有关常用继承方法的表,请参见JComponent API。
列表的大部分操作由其他对象 管理。列表中的项目由列表模型对象 管理,选择由列表选择模型对象 管理,大多数程序将列表放在滚动窗格中以处理滚动。在大多数情况下,您不必担心模型,因为JList
会根据需要创建它们,并且可以使用JList
的便捷方法与它们隐式地进行交互。
也就是说,使用列表的 API 分为以下几类:
方法或构造函数 | Purpose | |
---|---|---|
JList(ListModel) | ||
JList(Object[]) JList(Vector) JList() | 使用指定的初始列表项创建列表。第二个和第三个构造函数隐式创建一个不可变的ListModel ;您随后不应再修改传入的数组或Vector 。 | |
void setModel(ListModel) ListModel getModel() | 设置或获取包含列表内容的模型。 | |
void setListData(Object[]) void setListData(Vector) | 设置列表中的项目。这些方法隐式创建一个不可变的ListModel 。 | 。 |
Method | Purpose |
---|---|
void setVisibleRowCount(int) | |
int getVisibleRowCount() | 设置或获取visibleRowCount 属性。对于VERTICAL 布局方向,这无需滚动即可设置或获取要显示的首选行数。对于HORIZONTAL_WRAP 或VERTICAL_WRAP 布局方向,它定义了单元格的包装方式。有关更多信息,请参见setLayoutOrientation(int)。此属性的默认值为VERTICAL 。 |
void setLayoutOrientation(int) int getLayoutOrientation() | 设置或获取列表单元的布局方式。可能的布局格式由JList 定义的值VERTICAL (单元格的单列;默认值),HORIZONTAL_WRAP (“报纸”样式,其内容水平然后垂直流动)和VERTICAL_WRAP (“报纸”样式,其内容流动,指定)垂直然后水平)。 |
int getFirstVisibleIndex() int getLastVisibleIndex() | 获取第一个或最后一个可见项 Object 索引。 |
void ensureIndexIsVisible(int) | 滚动以使指定的索引在此列表所在的视口中可见。 |
Method | Purpose |
---|---|
void addListSelectionListener(ListSelectionListener) | 注册以接收选择更改的通知。 |
void setSelectedIndex(int) | |
void setSelectedIndices(int[]) void setSelectedValue(Object,boolean) void setSelectionInterval(int,int) | 按照指示设置当前选择。使用setSelectionMode 设置可接受的选择范围。布尔参数指定列表是否应try滚动自身以使所选项目可见。 |
int getAnchorSelectionIndex() int getLeadSelectionIndex() int getSelectedIndex() int getMinSelectionIndex() int getMaxSelectionIndex() int[] getSelectedIndices() Object getSelectedValue() Object[] getSelectedValues() | 按照指示获取有关当前选择的信息。 |
void setSelectionMode(int) int getSelectionMode() | 设置或获取选择 Pattern。可接受的值为:SINGLE_SELECTION ,SINGLE_INTERVAL_SELECTION 或MULTIPLE_INTERVAL_SELECTION (默认值),它们在ListSelectionModel 中定义。 |
void clearSelection() boolean isSelectionEmpty() | 设置或获取是否选择了任何项目。 |
boolean isSelectedIndex(int) | 确定是否选择了指定的索引。 |
类或方法 | Purpose |
---|---|
int getNextMatch(String,int,javax.swing.text.Position.Bias) | 给定起始索引,请在列表中搜索以指定字符串 开头的项目,然后返回该索引(如果找不到该字符串,则返回-1)。指定搜索方向的第三个参数可以是Position.Bias.Forward 或Position.Bias.Backward 。例如,如果您有一个 6 项列表,则getNextMatch("Matisse", 5, javax.swing.text.Position.Bias.Forward) 在索引 5 的项目中搜索字符串“ Matisse”,然后(如有必要)在索引 0,索引 1 等等中搜索字符串。 |
void setDragEnabled(boolean) | |
boolean getDragEnabled() | 设置或获取确定是否启用自动拖动处理的属性。有关更多详细信息,请参见拖放和数据传输。 |
使用列表的示例
下表显示了使用JList
的示例,并在其中描述了这些示例。
Example | Where Described | Notes |
---|---|---|
SplitPaneDemo | 如何使用分割窗格 | 包含一个单选的,不变的列表。 |
ListDemo | This section | 演示如何在运行时从列表添加和删除项目。 |
ListDialog | 本部分如何使用 BoxLayout | 用单选列表实现 Pattern 对话框。 |
ListDataEventDemo | 如何编写列表数据侦听器 | 演示侦听列表模型上的列表数据事件。 |
ListSelectionDemo | 如何编写列表选择监听器 | 包含共享相同选择模型的列表和表。您可以动态选择选择 Pattern。 |
SharedModelDemo | Using Models | 修改ListSelectionDemo ,以便列表和表共享相同的数据模型。 |
CustomComboBoxDemo | 提供自定义渲染器 | 显示如何为组合框提供自定义渲染器。由于列表和组合框使用相同类型的渲染器,因此您可以使用从那里学到的知识将其应用于列表。实际上,列表和组合框可以共享一个渲染器。 |
请参阅使用 JavaFX UI 控件:列表视图教程,以了解如何在 JavaFX 中创建列表。