在 Java Swing 中,列表框(JList)是用于显示一组选项的组件,用户可以从中选择一个或多个项目。以下是关于 Swing 列表框的详细介绍:
1. 基本概念与用途
- 作用:以垂直列表形式展示选项,支持单选或多选。
- 常见场景:文件选择、联系人列表、设置选项等。
2. 核心类与方法
Swing 列表框的核心类是 JList
,它继承自 JComponent
,主要方法包括:
构造方法:
JList() // 创建空列表 JList(Object[] listData) // 通过数组创建列表 JList(Vector<?> listData) // 通过 Vector 创建列表 JList(ListModel<?> dataModel) // 通过数据模型创建列表
选择操作:
setSelectionMode(int mode) // 设置选择模式 setSelectedIndex(int index) // 选择指定索引的项 setSelectedIndices(int[] indices) // 选择多个项 getSelectedIndex() // 获取选中项的索引 getSelectedIndices() // 获取所有选中项的索引 getSelectedValue() // 获取选中项的值 getSelectedValuesList() // 获取所有选中项的值列表
外观设置:
setVisibleRowCount(int n) // 设置可见行数 setFixedCellWidth(int width) // 设置固定单元格宽度 setFixedCellHeight(int height) // 设置固定单元格高度 setLayoutOrientation(int orientation) // 设置布局方向(水平/垂直)
3. 选择模式
通过 setSelectionMode(int mode)
方法设置选择模式,可选值为:
ListSelectionModel.SINGLE_SELECTION
:单选模式。ListSelectionModel.SINGLE_INTERVAL_SELECTION
:连续多选模式(通过 Shift 键)。ListSelectionModel.MULTIPLE_INTERVAL_SELECTION
:任意多选模式(通过 Ctrl 键或鼠标拖拽)
JList
是 Swing 中的一个组件,它显示一组固定的对象列表,允许用户从中进行选择。这些对象通常以文本形式显示,但也可以是图标或其他组件。JList
本身并不提供滚动功能,因此如果列表项超出可视区域,通常需要将其放置在一个 JScrollPane
中。
创建 JList
创建一个简单的 JList
可以通过以下几种方式:
- 基于数组:适用于已知固定数量的选项。
- 基于 Vector 或 基于 ListModel:更灵活,适合动态数据集。
import javax.swing.*;
public class JListExample {
public static void main(String[] args) {
JFrame frame = new JFrame("JList 示例");
DefaultListModel<String> listModel = new DefaultListModel<>();
listModel.addElement("苹果");
listModel.addElement("香蕉");
listModel.addElement("橙子");
JList<String> list = new JList<>(listModel);
JScrollPane scrollPane = new JScrollPane(list);
frame.add(scrollPane);
frame.setSize(300, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
重要属性与方法
- setSelectionMode(int mode): 设置选择模式,如单选(
ListSelectionModel.SINGLE_SELECTION
)、单间隔多选(ListSelectionModel.SINGLE_INTERVAL_SELECTION
)或多重任意选择(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION
)。 - getSelectedIndex() / getSelectedIndices(): 获取选中的索引或索引数组。
- getSelectedValue(): 获取当前选中的值。
- addListSelectionListener(ListSelectionListener listener): 添加监听器以响应选择变化事件。
交互与事件处理
为了响应用户的交互,比如选择了不同的列表项,你可以添加一个 ListSelectionListener
来监听选择的变化。
list.addListSelectionListener(e -> {
if (!e.getValueIsAdjusting()) {
System.out.println("选中的项目: " + list.getSelectedValue());
}
});
这里,getValueIsAdjusting()
方法用来判断用户是否还在拖动选择范围,避免在连续选择时多次触发事件。
4.综合示例:水果选择列表
下面是一个列表框示例,允许用户选择喜欢的水果:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class ListExample {
public static void main(String[] args) {
// 创建 JFrame
JFrame frame = new JFrame("水果选择列表");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(300, 300);
frame.setLocationRelativeTo(null);
// 创建水果数据
String[] fruits = {"苹果", "香蕉", "橙子", "葡萄", "草莓", "西瓜"};
// 创建列表框
JList<String> fruitList = new JList<>(fruits);
fruitList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
fruitList.setVisibleRowCount(5); // 设置可见行数
// 添加滚动条
JScrollPane scrollPane = new JScrollPane(fruitList);
// 创建按钮和结果标签
JButton selectButton = new JButton("确定选择");
JLabel resultLabel = new JLabel("你选择了: ");
selectButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
StringBuilder selectedFruits = new StringBuilder();
for (String fruit : fruitList.getSelectedValuesList()) {
selectedFruits.append(fruit).append("、");
}
if (selectedFruits.length() > 0) {
selectedFruits.deleteCharAt(selectedFruits.length() - 1); // 删除最后一个顿号
} else {
selectedFruits.append("无");
}
resultLabel.setText("你选择了: " + selectedFruits);
}
});
// 添加组件到面板
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
panel.add(scrollPane, BorderLayout.CENTER);
JPanel buttonPanel = new JPanel();
buttonPanel.add(selectButton);
buttonPanel.add(resultLabel);
panel.add(buttonPanel, BorderLayout.SOUTH);
frame.add(panel);
frame.setVisible(true);
}
}
5. 数据模型(ListModel)
JList 的数据可以通过 ListModel
动态管理,常用的实现类是 DefaultListModel
:
// 使用 DefaultListModel 创建可动态更新的列表
DefaultListModel<String> model = new DefaultListModel<>();
model.addElement("选项1");
model.addElement("选项2");
model.addElement("选项3");
JList<String> dynamicList = new JList<>(model);
// 动态添加元素
model.addElement("选项4");
// 动态删除元素
model.removeElement("选项2");
6. 自定义渲染器(ListCellRenderer)
通过自定义渲染器,可以改变列表项的外观(如颜色、图标、字体等):
// 自定义渲染器示例:为偶数行设置不同背景色
class CustomRenderer extends DefaultListCellRenderer {
@Override
public Component getListCellRendererComponent(JList<?> list, Object value,
int index, boolean isSelected,
boolean cellHasFocus) {
Component c = super.getListCellRendererComponent(list, value, index,
isSelected, cellHasFocus);
// 偶数行设置灰色背景
if (index % 2 == 0 && !isSelected) {
c.setBackground(Color.LIGHT_GRAY);
}
return c;
}
}
// 使用自定义渲染器
fruitList.setCellRenderer(new CustomRenderer());
7. 事件监听
通过 ListSelectionListener
监听列表选择变化:
fruitList.addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
if (!e.getValueIsAdjusting()) { // 防止多次触发
System.out.println("选中项索引: " + fruitList.getSelectedIndex());
System.out.println("选中项值: " + fruitList.getSelectedValue());
}
}
});
8. 水平布局与包装
通过 setLayoutOrientation
方法可以设置水平布局:
// 水平布局,自动换行
fruitList.setLayoutOrientation(JList.HORIZONTAL_WRAP);
fruitList.setVisibleRowCount(0); // 0 表示根据内容自动计算行数
总结
Swing 列表框是一个功能丰富的组件,通过合理使用数据模型、选择模式和渲染器,可以满足各种复杂需求。注意在处理大量数据时使用虚拟列表(JList
默认支持)以提高性能。