1

I have created a GUI and have a database located externally in which I fetch data from. I am using the GUI builder in NetBeans to do this. Does anyone know of a simple way to populate a jComboBox with values coming from the database? When I run the project there are no errors but the combo box remains empty.

Here is the code that sets the combo box with the names of discounts:

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);
    } 
}

This is located in a seperate class from the jComboBox object. This class is called Model.

Here is the place I call the setDiscountNames method in a form called DiscountGUIView:

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

Okay (Update) the query does print the results:

run:

Travel Standard Fixed Standard BUILD SUCCESSFUL (total time: 1 second)

mKorbel
  • 109,525
  • 20
  • 134
  • 319
JP24
  • 207
  • 3
  • 6
  • 13

3 Answers3

3

It might be that your SELECT query returns no results. To verify this, you can add logging statements inside the while (rs.next()) loop. My SQL knowledge is a bit rusty, but I remember using ' (single quotes) for string literals, whereas you use " (double quotes) in your statement.

Besides that, I see several things which could cause problems:

  • The SQL code for PreparedStatement should not be created by string concatenation. Instead, use ? for parameter values which will be substituted into the statement, e.g.

    stmt = con.prepareStatement("SELECT Name FROM Discount WHERE Type = ?");
    stmt.setString(1, type); // first (and only) parameter
    rs = stmt.executeQuery();
    
  • It is strongly recommended that you explicitly close JDBC resources after being done with them. For this, you need to add a finally block after the catch (SQLException ...), e.g.

    } 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) {}
    }
    

    or, preferrably, use the try-with-resources statement (if you are using Java 7 and higher):

    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
    
nvamelichev
  • 398
  • 3
  • 13
  • Would you need to quote the parameter (`'?'`)? – MadProgrammer Mar 19 '14 at 23:32
  • Tried this all but it didn't work unfortunately. Double quotes do work for sql statements. I've done many other ones and all of them have worked fine but I have been populating JTables and text fields really and this is the first ever time I'm trying to populate a JComboBox. – JP24 Mar 19 '14 at 23:33
  • @MadProgrammer no, quotes are not needed. Corrected my answer – nvamelichev Mar 19 '14 at 23:35
  • @JP24 If you change your `while (rs.next())` loop body to this: `String name = rs.getString("Name"); Logger.getLogger(Model.class.getName()).warning(name);`, does it print anything? You should also try to step into the loop with debugger, to see if the loop body even executes once... – nvamelichev Mar 19 '14 at 23:39
3

When trying to add elements dynamically to a combo box, use MutableComboBoxModel.addElement

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

To remove all elements you could also do

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

Using the model methods will fire the necessary changes to update the ui

Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
  • Right when did a system.out on this and checked the value of each position of the jcombobox index. The values successfully printed. However now the problem lies in me actually seeing these when I run the GUI and when I click on the drop down box and I can't seem to see the values there. The jComboBox is blank. :S – JP24 Mar 20 '14 at 00:02
  • Try using this and see what happens – Paul Samsotha Mar 20 '14 at 00:06
  • Did that, but when I run the whole project and I click on the JComboBox nothing seems to appear, however when doing a system.out.print the values within the index of the model are successfully printed to the terminal. – JP24 Mar 20 '14 at 00:11
  • If you have initial data you want shown in the combo box, then you need to add all your elements to the model to start. – Paul Samsotha Mar 20 '14 at 00:13
  • Like `DefaultComboBoxModel(myDataArray)` – Paul Samsotha Mar 20 '14 at 00:14
  • I'm sorry I'm really new to this stuff, can you explain more with the DefeaultComboBoxModel(myDataArray) thing please I'm confused :S. – JP24 Mar 20 '14 at 00:22
  • The `DefaultComboBoxModel` is a just a data structure to hold the data of the combo box. So instead of passing your initial data straight to the combobox `new JComboBox(myDataArray)`, you will be passing it the `DefaultComboBoxModel` which is then passed to the `JComboBox` ie `new JComboBox(new DefaultComboBoxModel(myDataArray))` – Paul Samsotha Mar 20 '14 at 00:27
  • You can obtain a reference to the `DefaultComboBoxModel` by using `cBox.getModel()`. And with the reference, you can use it's methods. The reason you want to use it is because it automatically update the ui when dynamically adding or removing elements, something `JComboBox.addItem` _doesn't_ do. Get it? – Paul Samsotha Mar 20 '14 at 00:28
  • Right I understand and when I am passing my data structure would it be exactly just doing DefaultComboBoxModel(the array I'm passing here) literally? – JP24 Mar 20 '14 at 00:38
  • Pretty much. _`"the array I'm passing here"`_ is the initial data for the combo box. After that, you never have to do it again. Just manipulate the `DefaultComboBoxModel` with its methods like `removeAllElements` and `addElement` – Paul Samsotha Mar 20 '14 at 00:40
2

EDIT: This is your basic mistake.. you're calling the method in ActionPerformed !!

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

}

If the values are printing correctly then try this..

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

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


    }
cbox.addItem(strings);
Sharp Edge
  • 4,144
  • 2
  • 27
  • 41
  • 1- This makes a better comment; 2- `Vector` is generally discouraged in favor of `List` and even in a multithreaded environment, `Collections.synchronizedList` is generally the preferred mechanism – MadProgrammer Mar 19 '14 at 23:32
  • I've been living my life a lie !! Damn .. My teacher told me to always use a Vector ... Can you please elaborate as why is Vector discouraged in favor of list ? – Sharp Edge Mar 19 '14 at 23:34
  • 1
    `Vector` is generally discouraged in favor of `List` as `List` doesn't make assumptions about the implementation (it is an `interface`), this allows you to make better decisions about how to implement the list (using a `ArrayList` for random access or `LinkedList` for sequential access for example). `Vector` is thread-safe by default, this has performance implications which you shouldn't need to care about if your list is been access by multiple threads. The Collections API allows you to make decisions about this as you need, allowing you to gain performance improvements – MadProgrammer Mar 19 '14 at 23:38
  • +1 So vector being thread safe by default has performance drawback as compared to list .. ? – Sharp Edge Mar 19 '14 at 23:43
  • 1
    That's the basic jist. `Vector` is also a implementation of `List` which has other considerations that might or might not be detrimental to the performance of your application. The other `List` implementations provide you choices about how the underlying implementation works and which is more suitable for your given situation... – MadProgrammer Mar 19 '14 at 23:45
  • I have tested the query through a system.print and it turns out the result set does return me the names of discounts. – JP24 Mar 19 '14 at 23:48
  • However I have the problem on getting these to show on my JComboBox – JP24 Mar 19 '14 at 23:48
  • edited my Answer @ JP24 .. for the love of Java if the values are not printing in the println, then they won't be added in the JComboBox.. – Sharp Edge Mar 20 '14 at 00:06
  • Are the values which you wana add .. printing in system.put.println(); ? Sounds to me that your values are not printing.. because their is no magic in populating a JComboBox !! – Sharp Edge Mar 20 '14 at 00:14
  • @Sharpedge run: [Travel Standard, Fixed Standard] [Travel Standard, Fixed Standard] BUILD SUCCESSFUL (total time: 2 seconds) Sorry for not being specific earlier so this prints out there should be exactly 2 items in the list Travel Standard and Fixed Standard but what I find funny is that these values are printed out repeatedly – JP24 Mar 20 '14 at 00:27
  • @ JP24 check my edit I just made ... you're calling the method in a wrong place buddy :D – Sharp Edge Mar 20 '14 at 00:28
  • @Sharpedge So basically what I am getting is at index 0 = [Travel Standard, Fixed Standard] rather than them being broken down in their own individual index? I also did a print on the item count of the combo box and it turns out it is 1 strangely and that too gets printed out twice. – JP24 Mar 20 '14 at 00:29
  • @Sharpedge Dude! almost there okay so basically the first item is [Travel Standard, Fixed Standard] as one option but I want them broken down into individual options. :D This is exciting! When I run the GUI I can see the first option in the combo box means almost there :D – JP24 Mar 20 '14 at 00:33
  • I solved you "populating the JComboBox Question" upvote and accept my answer :) and then start a new question as how to break them .. I'll answer that separately .. – Sharp Edge Mar 20 '14 at 00:37
  • @Sharpedge Right I'll do that now. Thanks! – JP24 Mar 20 '14 at 00:39
  • `cbox.addItem(strings);` won't work. This is adding the `ArrayList` to the combobox as a single element, not the individual elements in the list. Make a new `ComboBoxModel`, add the individual elements to it and then set the model to the combo box – MadProgrammer Mar 20 '14 at 00:55