如何使用清单

JList为用户提供一组项目,以一列或多列显示,供您选择。列表中可以包含许多项,因此它们通常放在scroll panes中。

除了列表之外,以下 Swing 组件还向用户显示多个可选项目:combo boxesmenustables以及check boxesradio buttons组。要显示分层数据,请使用tree

下图显示了两个使用列表的应用程序。本节将这些示例用作后续讨论的基础。

ListDialog

(由 ListDialogRunner 使用)
ListDemo

Try this:

  • 单击启动按钮以使用Java™Web 开始(下载 JDK 7 或更高版本)运行 ListDemo。另外,要自己编译和运行示例,请查阅example index

  • 单击启动按钮以运行 ListDialogRunner。或者,要自己编译和运行示例,请查阅example index

  • 要弹出 ListDialog,请在“命名那个婴儿”窗口中单击“选择新名称...”按钮。
    出现的对话框是一个 ListDialog 实例,该实例已被自定义为具有标题 Name Chooser。

  • 在 ListDemo 中,try添加(雇用)和删除(射击)一些物品。

本节的其余部分讨论以下主题:

创建模型

有三种创建列表模型的方法:

初始化列表

这是来自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。例如,ListDialogListDemo都将选择 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不满足您的需求,则可以编写一个自定义列表模型,该模型必须遵守ListModelinterface。

以下代码段显示了在 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方法在当前选择项之后(如果不存在选择项的话)在列表的开头插入新名称。如果您只想添加到列表的末尾,则可以使用DefaultListModeladdElement方法。

每当将项目添加到列表中,从列表中删除或在列表中进行修改时,列表模型都会触发列表数据事件。有关监听这些事件的信息,请参阅如何编写列表数据侦听器。该部分包含一个类似于ListDemo的示例,但添加了用于在列表中向上或向下移动项 Object 按钮。

编写自定义单元格渲染器

列表使用称为单元格渲染器的对象来显示其每个项目。默认的单元格渲染器知道如何显示字符串 和图标,并通过调用toString来显示Object。如果要更改默认渲染器显示图标或字符串 的方式,或者想要与toString提供的行为不同的行为,则可以实现自定义单元格渲染器。请按照以下步骤为列表提供自定义单元格渲染器:

我们没有提供带有自定义单元格渲染器的列表示例,但是我们提供了带有自定义渲染器的组合框示例-组合框使用与列表相同类型的渲染器。请参阅提供自定义渲染器中描述的示例。

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_WRAPVERTICAL_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_SELECTIONSINGLE_INTERVAL_SELECTIONMULTIPLE_INTERVAL_SELECTION(默认值),它们在ListSelectionModel中定义。
void clearSelection()
boolean isSelectionEmpty()
设置或获取是否选择了任何项目。
boolean isSelectedIndex(int) 确定是否选择了指定的索引。

管理 列表数据

类或方法 Purpose
int getNextMatch(String,int,javax.swing.text.Position.Bias) 给定起始索引,请在列表中搜索以指定字符串 开头的项目,然后返回该索引(如果找不到该字符串,则返回-1)。指定搜索方向的第三个参数可以是Position.Bias.ForwardPosition.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 中创建列表。

首页