You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复Java Swing中ComboBox的数据填充与联动问题?

球员与赛事管理程序的ComboBox数据加载问题修复

问题描述

我正在为足球俱乐部开发一款球员与赛事管理程序,采用SQLite数据库与Java Swing框架实现,程序包含两个ComboBox:一个用于选择类型(Spieler/Events),另一个用于显示对应球员或赛事名称。预期功能为切换类型ComboBox的选中项时,重新从数据库加载对应数据到第二个ComboBox中。

但当前代码存在两个问题:

  • 第二个ComboBox的数据填充显示异常;
  • 将type的声明移至配置函数时,会抛出空指针异常(Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.equals(Object)" because "selected" is null)。

用户提供的代码:

import javax.swing.*;
import java.awt.*;
import java.sql.*;
import java.text.MessageFormat;

public class MainWindow extends JFrame {
    private JPanel window;
    private JComboBox<String> comboBox2;
    private JButton deleteButton;
    private JComboBox<String> type = new JComboBox<>(new String[] {"Spieler", "Events"});

    private JButton addButton;
    private JButton changeButton;

    String selected = (String) type.getSelectedItem();

    Util util = new Util();

    MainWindow() throws SQLException{
        setConfigurations();
        reloadSelection(selected);
        type.addActionListener(e -> {
            try {reloadSelection((selected));}
            catch (SQLException ex) {throw new RuntimeException(ex);}

        });
        addButton.addActionListener(e -> System.out.println("not yet implemented"));
        deleteButton.addActionListener(e -> System.out.println("not yet implemented"));
        changeButton.addActionListener(e -> System.out.println("not yet implemented"));
    }

    private void  reloadSelection(String selected) throws SQLException {
        Connection c = util.getConnection();
        Statement stmt = c.createStatement();
        String[] arr = new String[0];
        String query;
        System.out.println(selected);
        if(selected.equals("Spieler")) {
            query = "SELECT firstName, lastName FROM Players;";
            ResultSet rs = stmt.executeQuery(query);
            while(rs.next()) {
                String name = rs.getString("firstName") + rs.getString("lastName");
                arr = name.split("\n");
            }
        }
        /*else if(selected.equals("Events")) {
            query = "SELECT eventName FROM Events;";
        } */
        comboBox2.setModel(new DefaultComboBoxModel<>(arr));
        util.closeConnection(c);
    }
    private void setConfigurations() {
        setContentPane(window);
        setName("LineUp");
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setSize(350, 175);
        setMaximumSize(new Dimension(350, 175));
        setMinimumSize(new Dimension(350, 175));
    }

}

问题分析与修复方案

1. 数据填充异常修复

问题原因

  • 遍历数据库结果集时,每次用arr = name.split("\n");覆盖数组,最终仅保留最后一条数据;
  • 球员姓名拼接时无空格分隔,导致名字连在一起;
  • Events分支被注释,无法加载赛事数据。

修复代码

改用List<String>动态存储数据,避免覆盖,同时完善赛事数据加载逻辑:

import java.util.ArrayList;
import java.util.List;

private void reloadSelection(String selected) throws SQLException {
    Connection c = util.getConnection();
    Statement stmt = c.createStatement();
    List<String> dataList = new ArrayList<>();
    String query;

    // 常量在前调用equals,避免空指针
    if("Spieler".equals(selected)) {
        query = "SELECT firstName, lastName FROM Players;";
        ResultSet rs = stmt.executeQuery(query);
        while(rs.next()) {
            // 姓名间添加空格分隔
            String name = rs.getString("firstName") + " " + rs.getString("lastName");
            dataList.add(name);
        }
    } else if("Events".equals(selected)) {
        query = "SELECT eventName FROM Events;";
        ResultSet rs = stmt.executeQuery(query);
        while(rs.next()) {
            dataList.add(rs.getString("eventName"));
        }
    }

    // 将List转为数组设置到ComboBox
    comboBox2.setModel(new DefaultComboBoxModel<>(dataList.toArray(new String[0])));
    util.closeConnection(c);
}

2. 空指针异常修复

问题原因

  • 类初始化阶段赋值selected,若type在setConfigurations中才初始化,此时type.getSelectedItem()返回null,后续调用equals会触发空指针;
  • 监听事件未实时获取最新选中项,始终使用初始化时的selected值。

修复步骤

  1. 移除类成员变量selected,每次调用方法时实时从type获取选中项;
  2. 若将type移至setConfigurations,确保初始化后再使用;
  3. 修改监听事件逻辑:
// 移除类成员变量String selected = ...

MainWindow() throws SQLException{
    setConfigurations();
    // 初始化时获取当前选中项
    reloadSelection((String) type.getSelectedItem());
    type.addActionListener(e -> {
        try {
            // 实时获取最新选中的类型
            reloadSelection((String) type.getSelectedItem());
        } catch (SQLException ex) {
            throw new RuntimeException(ex);
        }
    });
    // 其他按钮监听逻辑保持不变
}

// 若将type移至setConfigurations,修改该方法:
private void setConfigurations() {
    // 先初始化type
    type = new JComboBox<>(new String[] {"Spieler", "Events"});
    setContentPane(window);
    setName("LineUp");
    setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    setSize(350, 175);
    setMaximumSize(new Dimension(350, 175));
    setMinimumSize(new Dimension(350, 175));
}

额外优化建议

  • 使用PreparedStatement替代Statement,规避SQL注入风险;
  • 采用try-with-resources语法自动关闭数据库资源(Connection、Statement、ResultSet);
  • 为ComboBox添加默认提示文本,比如"请选择类型...";
  • 处理空结果集场景,避免ComboBox无内容显示。

内容的提问来源于stack exchange,提问作者Paval1s

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 09:36:00