JSpinnerListModel列表模型

wen java案例 1

本文目录导读:

JSpinnerListModel列表模型

  1. 基本概念
  2. 主要构造方法
  3. 基本使用示例
  4. 高级特性
  5. 注意事项
  6. 常见问题解决

JSpinnerListModel 是 Java Swing 中用于 JSpinner 组件的一种数据模型,它允许你通过一个列表(数组或 List)来定义 JSpinner 中显示的可用选项。

基本概念

JSpinnerListModel 允许用户通过向上/向下箭头或键盘在预定义的列表值之间循环选择。

主要构造方法

// 使用数组创建
JSpinnerListModel(Object[] items)
// 使用 List 创建
JSpinnerListModel(List<?> items)
// 使用 SpinnerListModel 的子类
SpinnerListModel(Object[] values)
SpinnerListModel(List<?> values)

基本使用示例

示例1:使用数组创建简单列表

import javax.swing.*;
import java.awt.*;
public class JSpinnerListExample {
    public static void main(String[] args) {
        JFrame frame = new JFrame("JSpinner 列表模型示例");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new FlowLayout());
        // 创建字符串数组
        String[] items = {"星期一", "星期二", "星期三", "星期四", "星期五"};
        // 创建 SpinnerListModel
        SpinnerListModel model = new SpinnerListModel(items);
        // 创建 JSpinner 并设置模型
        JSpinner spinner = new JSpinner(model);
        // 设置初始值(默认是第一个)
        spinner.setValue("星期三");
        frame.add(spinner);
        frame.setSize(300, 200);
        frame.setVisible(true);
    }
}

示例2:使用自定义对象

import javax.swing.*;
import java.awt.*;
public class CustomObjectListExample {
    public static void main(String[] args) {
        JFrame frame = new JFrame("自定义对象列表");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new FlowLayout());
        // 创建自定义对象数组
        Product[] products = {
            new Product("笔记本电脑", 5999),
            new Product("手机", 3999),
            new Product("平板电脑", 2999)
        };
        // 创建列表模型
        SpinnerListModel model = new SpinnerListModel(products) {
            @Override
            public Object getValue() {
                return super.getValue();
            }
        };
        // 创建自定渲染器显示产品名称
        JSpinner spinner = new JSpinner(model);
        // 自定义渲染器
        JSpinner.ListEditor editor = new JSpinner.ListEditor(spinner) {
            {
                getTextField().setEditable(false);
            }
        };
        frame.add(spinner);
        frame.setSize(300, 200);
        frame.setVisible(true);
    }
}
class Product {
    String name;
    double price;
    Product(String name, double price) {
        this.name = name;
        this.price = price;
    }
    @Override
    public String toString() {
        return name + " - ¥" + price;
    }
}

示例3:带事件监听的复杂示例

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
public class AdvancedListExample extends JFrame {
    private JLabel statusLabel;
    private JSpinner spinner;
    public AdvancedListExample() {
        setTitle("高级列表模型示例");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new BorderLayout());
        // 创建数据
        String[] cities = {"北京", "上海", "广州", "深圳", "成都", "杭州"};
        int[] populations = {2154, 2428, 1530, 1756, 1658, 1220}; // 单位:万
        // 创建组合数据模型
        Object[][] cityData = new Object[cities.length][2];
        for (int i = 0; i < cities.length; i++) {
            cityData[i] = new Object[]{cities[i], populations[i]};
        }
        // 创建列表模型
        SpinnerListModel model = new SpinnerListModel(cityData);
        // 创建 Spinner
        spinner = new JSpinner(model);
        spinner.setFont(new Font("微软雅黑", Font.PLAIN, 14));
        // 添加变化监听
        spinner.addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                updateStatus();
            }
        });
        // 创建标签
        statusLabel = new JLabel("请选择城市");
        statusLabel.setFont(new Font("微软雅黑", Font.PLAIN, 12));
        statusLabel.setHorizontalAlignment(JLabel.CENTER);
        // 布局
        JPanel centerPanel = new JPanel(new FlowLayout());
        centerPanel.add(new JLabel("选择城市:"));
        centerPanel.add(spinner);
        add(centerPanel, BorderLayout.CENTER);
        add(statusLabel, BorderLayout.SOUTH);
        setSize(400, 200);
        setLocationRelativeTo(null);
        // 更新状态
        updateStatus();
    }
    private void updateStatus() {
        Object[] selectedData = (Object[]) spinner.getValue();
        String city = (String) selectedData[0];
        int population = (int) selectedData[1];
        statusLabel.setText(String.format("已选择 %s,人口约 %d 万", city, population));
    }
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            new AdvancedListExample().setVisible(true);
        });
    }
}

高级特性

动态修改列表

public class DynamicListExample {
    public static void main(String[] args) {
        // 使用 List 实现动态修改
        java.util.List<String> dynamicList = new java.util.ArrayList<>();
        dynamicList.add("选项A");
        dynamicList.add("选项B");
        dynamicList.add("选项C");
        SpinnerListModel model = new SpinnerListModel(dynamicList);
        JSpinner spinner = new JSpinner(model);
        // 添加新选项
        JButton addButton = new JButton("添加选项D");
        addButton.addActionListener(e -> {
            dynamicList.add("选项D");
            // 重置模型
            spinner.setModel(new SpinnerListModel(dynamicList));
        });
    }
}

循环与非循环模式

// 默认是循环模式(到达末尾后回到开头)
SpinnerListModel model = new SpinnerListModel(items);
// 可以通过设置实现非循环模式(实际 SpinnerListModel 不支持直接设置)
// 需要自定义模型或监听状态

自定义渲染器

JSpinner spinner = new JSpinner(model);
JSpinner.ListEditor editor = new JSpinner.ListEditor(spinner);
// 自定义字体和颜色
JFormattedTextField textField = editor.getTextField();
textField.setFont(new Font("Arial", Font.BOLD, 18));
textField.setForeground(Color.BLUE);
textField.setBackground(Color.LIGHT_GRAY);

注意事项

  1. 类型安全:所有列表元素应该是相同类型或兼容类型
  2. 不可变列表:如果使用数组,数组内容可以修改,但数组长度固定
  3. 初始值:默认选中列表的第一个元素
  4. null 值:避免在列表中包含 null 值,会导致异常
  5. 线程安全:Swing 组件操作应在 EDT 线程中进行

常见问题解决

问题1:修改列表后 Spinner 不更新

// 解决方法:重新设置模型
spinner.setModel(new SpinnerListModel(updatedList));

问题2:自定义对象的显示

// 确保自定义类重写 toString() 方法
@Override
public String toString() {
    return this.name + " - " + this.value;
}

问题3:值变化监听

spinner.addChangeListener(e -> {
    Object value = spinner.getValue();
    // 处理值变化
});

JSpinnerListModel 是创建有限选项选择器的理想方式,特别适合用于设置、配置、选择器等场景。

抱歉,评论功能暂时关闭!