0

I'm trying to create a JComboBox that will hold Playlist objects in it. I want to have it hold the Playlist's String title, which is the key/display value, and a reference to the actual Playlist so it can be directly accessed when a user clicks a button relating to the selected Playlist. The contents of the combo box will be dynamically changed by the user so someone in another question suggested using the DefaultComboBoxModel to allow it to update itself. I saw this question Adding items to a JComboBox recommended wrapping the item in a new class. I tried this but now my combo box comes up blank.

My old code:

String[] playlistsStringArray = {"Library"};
JComboBox playlists = new JComboBox(playlistsStringArray);
DefaultComboBoxModel model;

// worked but only held strings.  I was having trouble referencing the playlist itself
model = new DefaultComboBoxModel(playlistsStringArray);  
playlists.setModel(model); 

My current code:

ComboItem myLibCombo = new ComboItem("Library", myLibrary);
DefaultComboBoxModel model;
ComboItem[] comboItems = new ComboItem[0];
JComboBox comboPlaylists = new JComboBox(comboItems);

// empty combo box
model = new DefaultComboBoxModel(comboItems);  
comboPlaylists.setModel(model); 
comboPlaylists.addItem(myLibCombo);

Also tried:

ComboItem myLibCombo = new ComboItem("Library", myLibrary);
DefaultComboBoxModel model;
ComboItem[] comboItems = {myLibCombo};
JComboBox comboPlaylists = new JComboBox(comboItems);

// empty combo box
model = new DefaultComboBoxModel(comboItems);  
comboPlaylists.setModel(model); 

Is there an easier way to do this? Or is my best option to have the playlists held in an array and search for a matching title each time? Any suggestions would be appreciated, thanks.

Community
  • 1
  • 1
Alex
  • 5
  • 1
  • 5

2 Answers2

1

I saw this question Adding items to a JComboBox recommended wrapping the item in a new class. I tried this but now my combo box comes up blank.

Yes, that is the easiest solution.

I tried this but now my combo box comes up blank.

Then you did something wrong. The trick is to just make sure you override the toString() method of your ComboItem class. You didn't post a proper SSCCE so we can't guess what you did wrong.

For more information, you can check out Combo Box With Hidden Data which explains this concept in more detail.

Some people don't like the idea of overrding the toString() method, in which case you can check out Combo Box With Custom Renderer for a more complete approach when using a custom renderer.

camickr
  • 321,443
  • 19
  • 166
  • 288
  • +1, if you want to render your items in a non-standard way, write a renderer. It's also the method used and explained in the official [tutorial](http://docs.oracle.com/javase/tutorial/uiswing/components/combobox.html) on `JComboBox` – Ordous May 16 '14 at 15:27
0

Here I will use an example I created using Employee objects instead of Playlist objects.

JComboBox cmbEmployees = new JComboBox<Employee>();
EmployeeListListener itemListener = new EmployeeListListener();
cmbEmployees.addItemListener(itemListener);

Here is a method that gets called to populate the JComboBox every time the panel containing the JComboBox gets loaded.

public void updateEmployees() {
    cmbEmployees.removeAllItems();
    Collections.sort(frmMain.empDao.employees);
    for (Employee emp : frmMain.empDao.employees) {
        cmbEmployees.addItem(emp);
    }
}

And here is the inner listener class that determines which Employee is currently selected

public class EmployeeListListener implements ItemListener {

    /**
     * Creates a new listener
     * 
     * @param frmMain
     *            .empDb The file of employees
     * @param frmMain
     *            The main frame.
     */
    public EmployeeListListener() {

    }

    @Override
    /**
     * Handles item state changes to update the selected employee.
     */
    public void itemStateChanged(ItemEvent e) {

        if (e.getSource() instanceof JComboBox) {
            JComboBox<?> c = (JComboBox<?>) e.getSource();
            if (c.getSelectedItem() != null
                    && (e.getStateChange() == ItemEvent.SELECTED)) {
                if (frmMain.empDao.employees.contains(c.getSelectedItem())) {
                    selectedEmp = (Employee) c.getSelectedItem();
                    frmMain.pnlEmployeeMenu.clearFields();
                }

                else if (c.getSelectedItem() instanceof String) {
                    String username = (String) c.getSelectedItem();
                    for (Employee emp : frmMain.empDao.employees) {
                        if (emp.getUsername().equalsIgnoreCase(username)) {
                            selectedEmp = emp;
                            frmMain.pnlEmployeeMenu.clearFields();
                            return;
                        }
                    }
                    System.out.println("No such employee");
                }
            }
        }
    }
}

Now you can access the currently selected Employee object anywhere you can access the JComboBox by saying

cmbEmployees.getSelectedItem();

Oh, and to have the JComboBox display a specified String you would need to override the toString() method in the Playlist class, for example

@Override
public String toString() {
    return playlistName();
}

Hope this helped.

secondbreakfast
  • 4,194
  • 5
  • 47
  • 101