如何使用清单

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

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

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

ListDialog 的快照,显示一个简单的列表ListDemo 的快照,可让您添加和删除列表项
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并实现从ListModelinterface继承的getSizegetElementAt方法。

  • 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_WRAPVERTICAL_WRAPVERTICAL
HORIZONTAL_WRAPVERTICAL_WRAPVERTICAL

结合对setLayoutOrientation的调用,调用setVisibleRowCount(-1)可使列表在屏幕上的可用空间中显示最大数量的项目。 setVisibleRowCount的另一个常见用法是在列表的滚动窗格中指定列表希望显示多少行。

选择列表中的项目

列表使用ListSelectionModel的实例来 管理 其选择。默认情况下,列表选择模型允许一次选择项 Object 任何组合。您可以通过调用列表上的setSelectionMode方法来指定其他选择 Pattern。例如,ListDialogListDemo都将选择 Pattern 设置为SINGLE_SELECTION(由ListSelectionModel定义的常数),以便只能选择列表中的一项。下表描述了三种列表选择 Pattern:

ModeDescription
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提供的行为不同的行为,则可以实现自定义单元格渲染器。请按照以下步骤为列表提供自定义单元格渲染器:

  • 编写一个实现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

显示列表

MethodPurpose
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)滚动以使指定的索引在此列表所在的视口中可见。

管理 列表的选择

MethodPurpose
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的示例,并在其中描述了这些示例。

ExampleWhere DescribedNotes
SplitPaneDemo如何使用分割窗格包含一个单选的,不变的列表。
ListDemoThis section演示如何在运行时从列表添加和删除项目。
ListDialog本部分如何使用 BoxLayout用单选列表实现 Pattern 对话框。
ListDataEventDemo如何编写列表数据侦听器演示侦听列表模型上的列表数据事件。
ListSelectionDemo如何编写列表选择监听器包含共享相同选择模型的列表和表。您可以动态选择选择 Pattern。
SharedModelDemoUsing Models修改ListSelectionDemo,以便列表和表共享相同的数据模型。
CustomComboBoxDemo提供自定义渲染器显示如何为组合框提供自定义渲染器。由于列表和组合框使用相同类型的渲染器,因此您可以使用从那里学到的知识将其应用于列表。实际上,列表和组合框可以共享一个渲染器。

请参阅使用 JavaFX UI 控件:列表视图教程,以了解如何在 JavaFX 中创建列表。