12.7Swing控件6 JList

在 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 可以通过以下几种方式:

  1. 基于数组:适用于已知固定数量的选项。

  2. 基于 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 默认支持)以提高性能。

相关推荐
程序员良辰2 分钟前
URL与URI:互联网世界的“门牌号“与“身份证“
java·网络协议
ahauedu11 分钟前
Apache POI 依赖版本冲突导致 NoSuchFieldError: Factory 报错
java·maven·apache
运维帮手大橙子35 分钟前
字符串缓冲区和正则表达式
java·开发语言
丶小鱼丶2 小时前
栈算法之【有效括号】
java·算法
郝学胜-神的一滴3 小时前
SpringBoot实战指南:从快速入门到生产级部署(2025最新版)
java·spring boot·后端·程序人生
鼠鼠我捏,要死了捏5 小时前
Java 虚拟线程在高并发微服务中的实战经验分享
java·microservices·virtualthreads
武子康6 小时前
Java-82 深入浅出 MySQL 内部架构:服务层、存储引擎与文件系统全覆盖
java·开发语言·数据库·学习·mysql·spring·微服务
Rancemy6 小时前
rabbitmq 03
java·分布式·rabbitmq
Dcs8 小时前
“SQL注入即服务”:一个10年历史系统的奇幻演变
java
秃了也弱了。8 小时前
reflections:Java非常好用的反射工具包
java·开发语言