【问题标题】:JComboBox - out of bounds exceptionJComboBox - 越界异常
【发布时间】:2026-01-23 18:50:01
【问题描述】:

我有一个小问题。我正在尝试将登录名从我的数据库导入到一个向量,然后将该向量用于 JComboBox。我下载登录的方法:

public void loginReader (Vector<String> loginy, String tableName)
{
    String query = "select login from " + tableName;

    try {

        Statement statement = mConnection.createStatement();
        ResultSet rs = statement.executeQuery(query);
        while (rs.next()) 
            {
             Vector<String> vstring = new Vector<String>();

                vstring.add(rs.getString("login"));


                loginy.addAll(vstring);
            }
        } catch (SQLException e)
            {
                e.printStackTrace();

            }
}

这是在数据库管理类中。我制作了另一个类(GUI),还有那个 JComboBox。为什么它不起作用?

package DataBase_Hospital;



 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.sql.Connection;
 import java.sql.DriverManager;
 import java.sql.SQLException;
 import java.text.ParseException;
 import java.util.Properties;
 import java.util.Vector;

 import javax.swing.ImageIcon;
 import javax.swing.JButton;
 import javax.swing.JComboBox;
 import javax.swing.JFrame;
 import javax.swing.JLabel;
 import javax.swing.JScrollPane;
 import javax.swing.JTextArea;
 import javax.swing.JTextField;


 public class Message extends JFrame implements ActionListener {



JButton SEND_MESSAGE;
JButton READ_MESSAGE;
public JLabel background;

JLabel NAME_LABEL;

JTextField NAME_FIELD;

JTextArea DATABASE_FIELD;
static Vector<String> loginy = new Vector<String>();

private static DatabaseManagement DATABASE;

public Message() {



    setSize(290, 500);
    setTitle("Message Panel");


    setLocationRelativeTo(null);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    setVisible(true);
    JLabel background=new JLabel(new ImageIcon("/Users/Dominik/Desktop/messageFrame.png"));
    add(background);


    DATABASE_FIELD = new JTextArea(3,3);
    JScrollPane scrollPane = new JScrollPane(DATABASE_FIELD);
    scrollPane.setBounds(45, 50, 200, 200);
    background.add(scrollPane);
    DATABASE_FIELD.setEditable(true);


    NAME_LABEL = new JLabel("Odbiorca :");
    NAME_LABEL.setBounds(40, 380, 140, 20);
    background.add(NAME_LABEL);

    SEND_MESSAGE = new JButton();
    SEND_MESSAGE.setIcon(new ImageIcon("/Users/Dominik/Desktop/sendMail.jpg"));
    SEND_MESSAGE.setBounds(75, 270, 60, 60);
    background.add(SEND_MESSAGE);
    SEND_MESSAGE.addActionListener(this);
    SEND_MESSAGE.setToolTipText("Send message");

    READ_MESSAGE = new JButton();
    READ_MESSAGE.setIcon(new ImageIcon("/Users/Dominik/Desktop/jwj.png"));
    READ_MESSAGE.setBounds(150, 270, 60, 60);
    background.add(READ_MESSAGE);
    READ_MESSAGE.addActionListener(this);
    READ_MESSAGE.setToolTipText("Read message");


  JComboBox loginList = new JComboBox(loginy);
  loginList.setSelectedIndex(loginy.capacity());
  loginList.addActionListener(this);
  loginList.setBounds(145, 380, 100, 20);
  background.add(loginList);

}

public static void main(String[] args) {

    Message window = new Message();
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    window.setVisible(true);
    DATABASE.loginReader(loginy,"uzytkownicy");
}

public void actionPerformed(ActionEvent e) 
{
    Object EVENT_SOURCE = e.getSource();
    DATABASE = new DatabaseManagement("pacjent");

    if (EVENT_SOURCE == SEND_MESSAGE) 
    {
        DATABASE.sendMessage(DATABASE_FIELD.getText(), "uzytkownicy", NAME_FIELD.getText()) ;
    }

}
}

【问题讨论】:

  • 如果你把你的代码问题告诉我们会很有帮助。
  • 完整的堆栈跟踪以及任何其他错误花絮都会有所帮助。
  • 我插入了我的代码,怎么了?
  • 编译后的消息是:线程“main”中的异常 java.lang.IllegalArgumentException: setSelectedIndex: 10 out of bounds at javax.swing.JComboBox.setSelectedIndex(JComboBox.java:622) at DataBase_Hospital。 Message.(Message.java:83) 在 DataBase_Hospital.Message.main(Message.java:92)
  • 只是一个评论,您对数据库的使用使您对 SQL 注入开放(如果表名可以包含来自用户的数据)。使用 PreparedStatements。

标签: java swing vector jcombobox indexoutofboundsexception


【解决方案1】:

用空的Vector 创建JComboBox 后,将selectedIndex 设置为loginy.capacity ()。问题是,虽然Vector 的容量为 10(如JavaDoc for the default constructor 中所述),但它的实际大小为 0。因此ArrayOutOfBoundsException。在设置JComboBox 的选定索引之前,您应该检查Vector 的大小。

【讨论】:

    【解决方案2】:

    我怀疑问题是您试图将组合框的选定索引设置为向量的容量。

    loginList.setSelectedIndex(loginy.capacity());
    

    来自文档.capacity()

    返回此向量的当前容量。 回报: 当前容量(其内部数据数组的长度,保存在该向量的elementData字段中)

    这不是大小,即数据库中的登录次数。这是内部数据结构的容量,它总是 >= 向量中的元素数。

    尝试使用Vector#size(),但您仍然需要从中减去一个(假设向量中有实际数据),因此您的代码应该是:

    loginList.setSelectedIndex(loginy.size() - 1); 
    

    这将设置组合框中的最后一次登录。在您的情况下这不是必需的,因为您在创建组合框后填充向量,因此您可以从代码中删除此行,直到填充向量。


    编辑根据 cmets

    您需要做的就是重新排序执行顺序。即填充您的矢量,然后创建您的组合框,将您的主要方法更改为如下内容:

    public static void main(String[] args) {
        //First initialise your database (dont do this in the action performed method)
        //  you should only need one and not need to create a new one on each action
        DATABASE = new DatabaseManagement("pacjent");
        // Read logins (I assume this is the method that does it)
        DATABASE.loginReader(loginy,"uzytkownicy");
        // Then create your message window...
        Message window = new Message();
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        window.setVisible(true);
    }
    

    【讨论】:

    • 谢谢你!现在程序开始了,但是当我点击我的 ComboBox 时,什么也没有发生...结束:DataBase_Hospital.Message.main(Message.java:96) 处的线程“main”java.lang.NullPointerException 中的异常
    • 这是因为您在构建组合框后使用数据填充向量,从数据库读取登录信息后,您需要使用数据更新组合框
    • 好的,我明白,但我不知道如何改变它。有什么建议吗?
    • 您可以在构建组合框之前填​​充向量,因此在创建 gui 之前从数据库中读取。或者当您从数据库中读取时,使用组合框 addItem(item) 方法将所有项目添加到组合框
    • 你能帮我更多吗?我正在尝试这样做,但我不知道该怎么做。你能写出正确的代码吗?谢谢!