0

I've created a ComboBoxModel class which extends AbstractListModel. I can add item to the combobox, but when I try to remove, I get an exception

Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: null source

at line

this.fireIntervalRemoved(selectedItem, itemIndex, itemIndex);

public class TComboBoxModel extends AbstractListModel implements ComboBoxModel {

    private int itemIndex; 

    private Object selectedItem = null;
    private ArrayList<Object> itemList;

    public TComboBoxModel() {
        itemList = new ArrayList<>();
    }

    public void addItem(String item) {
        this.itemList.add(item);
        this.fireIntervalAdded(item, itemIndex, itemIndex);
    }

    public void removeItem() {
        if (itemIndex >= 0 && itemIndex < getSize()) {
            this.itemList.remove(itemIndex);
            this.fireIntervalRemoved(selectedItem, itemIndex, itemIndex);
        }
    }

    @Override
    public void setSelectedItem(Object anObject) {
        if ((selectedItem != null && !selectedItem.equals(anObject)) || selectedItem == null && anObject != null) {
            this.selectedItem = anObject;
            this.fireContentsChanged(anObject, -1, -1);
        }
    }

    @Override
    public Object getSelectedItem() {
        return selectedItem;
    }

    @Override
    public int getSize() {
        return itemList.size();
    }

    @Override
    public Object getElementAt(int index) {
        return itemList.get(index).toString();
    }

    public int getItemIndex() {
        return itemIndex;
    }

    public void increaseItemIndex() {
        itemIndex++;
    }

    public void decreaseItemIndex() {
        itemIndex--;
    }

}
  • 3
    The stack trace seems fairly straight forward, I would suggest using a `DefaultComboBoxModel` though due to its simplicity. It appears you aren't doing anything *special* with your model which the `DefaultComboBoxModel` doesn't already do, so there isn't really a point in reinventing the wheel. – Josh M Aug 20 '13 at 21:51

2 Answers2

1

You should probably change it to say:

if (selectedItem != null) {
    fireIntervalRemoved(this, itemIndex, itemIndex);
}

Since you can't remove an item unless you know which one to remove by having a selected item.

You are going to have to be setting the itemIndex variable appropriately too.

public void setSelectedItem(Object anObject) {
    if ((selectedItem != null && !selectedItem.equals(anObject)) || selectedItem == null && anObject != null) {
        this.selectedItem = anObject;
        this.fireContentsChanged(anObject, -1, -1);
        itemIndex = ... index in itemList where anObject is located (or -1 if not found) ...
    }
}

Thanks to @kiheru for pointing out the problem with the 1st argument.

Lee Meador
  • 12,829
  • 2
  • 36
  • 42
1

Pass this to the fire* methods in the model. The event source is the model, not the item.

From the documentation:

source - the ListModel that changed, typically "this"

kiheru
  • 6,588
  • 25
  • 31
  • That works man, thanks alot! Should I put `this` also some where ? – Isaac Tobin Aug 20 '13 at 22:00
  • @IsaacTobin Sorry, I don't understand the question. – kiheru Aug 20 '13 at 22:01
  • I mean, in some other fire method ? Should I set it to each fire method ? – Isaac Tobin Aug 20 '13 at 22:05
  • 1
    @IsaacTobin It's the same for `fireIntervalAdded()` and `fireContentsChanged()`. I linked to the documentation - those methods are documented on the same page. (If it's about fire methods in other models, then it depends. Usually it's the same, but always refer to the documentation of the particular class). – kiheru Aug 20 '13 at 22:09