The JList constructor that we care about for this case takes an array of Objects, as Tony already pointed out. That's about where his answer stops being useful (no offense Tony).
By default, the ListCellRenderer that the JList uses adds JLabels that contain the text from Object#toString(). So, instead of passing Strings, you want to pass it an array of your User Objects, then add a ListSelectionListener (which is used after a user clicks on the JList) and a ListCellRenderer (which determines how a User object is translated into a JComponent that will be drawn as part of the JList).
You want to do something like this (see inline comments for details):
//generate your user data
User[] userData = ...;
//add an array of Objects to a JList using the constructor
//(all classes extend java.lang.Object, including User)
JList foo = new JList(userData);
//overwrite the ListCellRenderer. This will take care of just displaying
//the name of the user
foo.setCellRenderer(new DefaultListCellRenderer(){
JLabel rv = new JLabel();
@Override
public Component getListCellRendererComponent(JList list,
Object value, int index, boolean isSelected,
boolean cellHasFocus){
String s = (value != null && value instanceof User)? ((User)value).name:"";
rv.setText(s);
if (isSelected) {
rv.setBackground(list.getSelectionBackground());
rv.setForeground(list.getSelectionForeground());
} else {
rv.setBackground(list.getBackground());
rv.setForeground(list.getForeground());
}
rv.setEnabled(list.isEnabled());
rv.setFont(list.getFont());
rv.setOpaque(true);
return rv;
}
});
//Now overwrite the ListSelectionListener which will take care of getting
//user object when the user clicks it
foo.addListSelectionListener(new ListSelectionListener(){
@Override
public void valueChanged(ListSelectionEvent lse) {
User selectedValue = (User)((JList)lse.getSource()).getSelectedValue();
//now you can do something with the User Object that was just selected
updateDatabase(selectedValue.id, selectedValue.name,
selectedValue.location);
});