【问题标题】:How to populate data in a JComboBox?如何在 JComboBox 中填充数据?
【发布时间】:2014-03-19 22:59:53
【问题描述】:

我创建了一个 GUI,并有一个位于外部的数据库,我从中获取数据。我正在使用 NetBeans 中的 GUI 构建器来执行此操作。有谁知道用来自数据库的值填充 jComboBox 的简单方法?当我运行该项目时,没有错误,但组合框仍然为空。

这是设置带有折扣名称的组合框的代码:

public void setDiscountNames(String type, JComboBox cbox) {        
    cbox.removeAllItems();     
    ArrayList<Discount> names = new ArrayList<Discount>();
    try {        
        Connection con = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;            
        con = DriverManager.getConnection("jdbc:mysql://localhost:3306/abpp034?user=abpp034&password=120001772");
        stmt = con.prepareStatement("SELECT Name FROM Discount WHERE Type = \"" + type + "\"");
        rs = stmt.executeQuery();

     while(rs.next()){                     
         cbox.addItem(rs.getString("Name")); 
        }
    } catch (SQLException ex) {
        Logger.getLogger(Model.class.getName()).log(Level.SEVERE, null, ex);
    } 
}

它位于与 jComboBox 对象不同的类中。这个类称为模型。

这里是我在一个名为 DiscountGUIView 的表单中调用 setDiscountNames 方法的地方:

private void jComboBox1ActionPerformed(java.awt.event.ActionEvent evt){                                           
     model.setDiscountNames("Fixed", jComboBox1);
}                                          

好的(更新)查询会打印结果:

run:

旅行标准 固定标准 构建成功(总时间:1 秒)

【问题讨论】:

  • 您确定查询正在返回结果吗?
  • 是的,我很确定这是因为我在我的数据库所在的服务器上运行了这个 sql 查询,它成功地检索到了结果。
  • 但是你的程序呢?它是检索结果吗?尝试在rs.next while-loop 中添加System.out.println 语句...
  • 在尝试将项目动态添加到组合框时使用MutableComboBoxModel.addElement
  • 好的,所以我做了 system.out.print,这是我收到的错误:

标签: java netbeans jdbc jcombobox


【解决方案1】:

您的SELECT 查询可能没有返回任何结果。要验证这一点,您可以在 while (rs.next()) 循环内添加日志记录语句。我的 SQL 知识有点生疏,但我记得使用 '(单引号)表示字符串文字,而您在语句中使用 "(双引号)。

除此之外,我还发现了几件事可能会导致问题:

  • PreparedStatement 的 SQL 代码不应由字符串连接创建。相反,将? 用于将替换到语句中的参数值,例如

    stmt = con.prepareStatement("SELECT Name FROM Discount WHERE Type = ?");
    stmt.setString(1, type); // first (and only) parameter
    rs = stmt.executeQuery();
    
  • 强烈建议您在使用完 JDBC 资源后显式关闭它们。为此,您需要在catch (SQLException ...) 之后添加一个finally 块,例如

    } finally {
         try {
             if (rs != null) rs.close();
         } catch (SQLException ignore) {}
    
         try {
             if (stmt != null) stmt.close();
         } catch (SQLException ignore) {}
    
         try {
             if (conn != null) conn.close();
         } catch (SQLException ignore) {}
    }
    

    或者,最好使用try-with-resources 语句(如果您使用的是 Java 7 及更高版本):

    try (Connection con = DriverManager.getConnection(...)) {
        // ...
        try (PreparedStatement stmt = con.prepareStatement("SELECT Name FROM Discount WHERE Type = ?")) {
            // ...
            try (ResultSet rs = stmt.executeQuery()) {
                while (rs.next()) {
                    // processing
                }
            }
        }
    } catch (SQLException) {
        Logger....;
    } // notice no finally block; resources are closed automatically
    

【讨论】:

  • 是否需要引用参数('?')?
  • 尝试了这一切,但不幸的是它没有工作。双引号确实适用于 sql 语句。我做了很多其他的,所有的都运行良好,但我一直在填充 JTables 和文本字段,这是我第一次尝试填充 JComboBox。
  • @MadProgrammer 不,不需要引号。更正了我的答案
  • @JP24 如果您将while (rs.next()) 循环体更改为:String name = rs.getString("Name"); Logger.getLogger(Model.class.getName()).warning(name);,它会打印任何内容吗?您还应该尝试使用调试器进入循环,看看循环体是否甚至执行一次......
【解决方案2】:

当尝试将元素动态添加到组合框时,请使用MutableComboBoxModel.addElement

JComboBox box = new JComboBox(new DefaultComboBoxModel());
....
MutableComboBoxModel model = (DefaultComboBoxModel)box.getModel();
while (rs.next()) {
    model.addElement(rs.getString("Name"));
}

要删除你也可以做的所有元素

((DefaultComboBoxModel)box.getModel).removeAllElements();

使用模型方法将触发必要的更改以更新用户界面

【讨论】:

  • 正确的时候做了一个 system.out 并检查了 jcombobox 索引的每个位置的值。值已成功打印。然而,现在问题在于我在运行 GUI 时实际看到了这些,当我单击下拉框时,我似乎看不到那里的值。 jComboBox 是空白的。 :S
  • 试试这个看看会发生什么
  • 做到了,但是当我运行整个项目并单击 JComboBox 时,似乎什么也没有出现,但是在执行 system.out.print 时,模型索引中的值已成功打印到终端。
  • 如果您有想要在组合框中显示的初始数据,那么您需要将所有元素添加到模型中才能开始。
  • 点赞DefaultComboBoxModel(myDataArray)
【解决方案3】:

编辑:这是您的基本错误..您正在调用 ActionPerformed 中的方法!

classConstructor(){
setDiscountNames("Fixed", jComboBox1); // call this method here.. This will work.

}

如果值打印正确,那么试试这个..

List<String> strings = new ArrayList<String>();
while(rs.next()){

     strings.add(rs.getString("Name"));  // Confirm if "Name" is valid


    }
cbox.addItem(strings);

【讨论】:

  • 1- 这样评论更好; 2- Vector 通常不鼓励使用List,即使在多线程环境中,Collections.synchronizedList 通常也是首选机制
  • 我一直过着谎言的生活!!该死的..我的老师告诉我总是使用 Vector ......你能详细说明一下为什么不鼓励 Vector 支持列表吗?
  • Vector 通常不鼓励使用List,因为List 不会对实现做出假设(它是interface),这使您可以更好地决定如何实现列表(例如,使用ArrayList 进行随机访问或LinkedList 进行顺序访问)。 Vector 默认情况下是线程安全的,这具有性能影响,如果您的列表被多个线程访问,您不需要关心这些问题。 Collections API 允许您根据需要对此做出决定,从而提高性能
  • +1 因此,与 list 相比,默认情况下 vector 是线程安全的存在性能缺陷 .. ?
  • 这是基本要点。 Vector 也是 List 的一个实现,它有其他可能会或可能不会损害您的应用程序性能的考虑因素。其他List 实现为您提供有关底层实现如何工作以及更适合您的特定情况的选择...
猜你喜欢
  • 1970-01-01
  • 2019-08-14
  • 2014-10-02
  • 1970-01-01
  • 1970-01-01
  • 2010-11-20
  • 2012-04-07
  • 1970-01-01
  • 2017-12-19
相关资源
最近更新 更多