javajlistjdialog

How to get JList getSelectedValue() to return a Class Object?


I am using a JList that contains Objects of Houses with addresses. The Houses are in a TreeMap (Not sure if that was the best choice) in a Neighborhood class. I am using Map.Entry and .entryset() to add the House values to a DefaultListModel, and then adding that to my JList. When clicking on a House object in the list, I want a JDialog to pop up with all of the house properties such as address, number of floors etc. My issue is when I use getSelectedValue() from the ListSelectionListener, it will only return either a String in the form of .toString() or a generic Object type. In my JDialog how can I get each House property in its own text field? I can't seem to just do house.getAddress() since it doesn't allow me to pass it as a House object. I have tried casting list.SelectedValue() to a House but I end up getting an error of "class java.util.TreeMap$Entry cannot be cast to class House". I have no issues accessing the properties when I print them from the Map, but once they're in the JList that's when I run into issues.

Sorry if this seems like a dumb question or something doesn't make sense. I'm still very new to Java and programming in general!

DefaultListModel model = new DefaultListModel();
for (Map.Entry<String, House> value : neighborhood.houses.entrySet()) {

 System.out.println(value);
 //System.out.println(value.getValue().getAddress()); //< This seems to work
 model.addElement(value);
}

JList list = new JList(model);
list.addListSelectionListener(new ListSelectionListener() {
 public void valueChanged(ListSelectionEvent e) {
  if (!e.getValueIsAdjusting()) {
   System.out.println(list.getSelectedValue());
   House selectedObj = (House)list.getSelectedValue();
   HouseDialog houseDialog = new HouseDialog (selectedObj);
  }
 }
});

I get "class java.util.TreeMap$Entry cannot be cast to class House" as a result


Solution

  • You're adding the Map.Entry to your ListModel...

    for (Map.Entry<String, House> value : neighborhood.houses.entrySet()) {
        System.out.println(value);
        model.addElement(value);
    }
    

    Maybe you meant to do model.addElement(value.getValue()); instead?

    What you should (also) do, is make use of the generic support of the DefaultListModel and JList. This will provide you with compile time protection, meaning you can only add instances of House to your model and you don't need to cast the value when you retrieve it, for example...

    DefaultListModel<House> model = new DefaultListModel<>();
    for (Map.Entry<String, House> value : neighborhood.houses.entrySet()) {
        System.out.println(value);
        model.addElement(value.getValue());
    }
    
    JList<House> list = new JList<>(model);
    list.addListSelectionListener(new ListSelectionListener() {
        public void valueChanged(ListSelectionEvent e) {
            if (!e.getValueIsAdjusting()) {
                System.out.println(list.getSelectedValue());
                House selectedObj = list.getSelectedValue();
                HouseDialog houseDialog = new HouseDialog(selectedObj);
            }
        }
    });
    

    This assumes you only want the House and not the Map.Entry<String, House>. You could still make use of the Map.Entry if you wanted to following the same basic idea, just that you'd need to use Map.Entry#getValue to get the reference to to House before displaying it.