user3226170
user3226170

Reputation: 175

Removing an item from a JList

I know this question has been asked before, and there are lots of threads where I could cut and paste working code, but my question is about why the code I have below doesn't work. I am trying to remove multiple items from a JList, but when I run the following code I get an out of bounds exception. Here's the snippit:

static DefaultListModel<File> listModel = new DefaultListModel<>();
JList<File> fileList = new JList<>(listModel);

void removeFiles() {
    int[] listRange = new int[100];
    listRange = fileList.getSelectedIndices();
    int i = 0;
    while (i <= listRange.length) {
        listModel.remove(listRange[i]);
        i++;
    }
}

I've used debug statements to confirm that fileListis getting the data (i.e. if I add 4 files its length is 4), and I've also confirmed that the indices in listRange represent the indexes of the files which I want to remove. But for some reason, it won't remove them. I've tried removing from fileList, as well as from the model (listModel), but neither will work. Am I overlooking something here? Thanks.

Upvotes: 0

Views: 304

Answers (2)

Roel Strolenberg
Roel Strolenberg

Reputation: 2950

The out of the box solution would be to remove items in reverse order as to avoid the out of bounds exception:

int[] listRange = fileList.getSelectedIndices();
int i = listRange.length-1;
while (i >= 0) {
    listModel.remove(listRange[i]);
    i--;
}

Upvotes: 0

Adel Boutros
Adel Boutros

Reputation: 10285

When you remove an item from the list, its size will decrease.

So for example in a list of 3 items, you want to remove item at index 1 and 2. When you remove the first one, the list has only 2 items remaining at index 0 and 1. So calling list.remove(2) will result in an outOfBoundException

A possible solution is to use the iterator and keep calling next until you reach one of the indices you want to remove and you call remove on it. Or simply decrease the next index to remove by the number of removal already performed

PS: this only works if getSelectedIndices returns an ordered array. Otherwise, you have to order the indices yourself

static DefaultListModel<File> listModel = new DefaultListModel<>();
JList<File> fileList = new JList<>(listModel);

void removeFiles() {
    int[] listRange = new int[100];
    listRange = fileList.getSelectedIndices();
    int i = 0;
    //The counter of the removed items so far
    int nbOfRemovedItems = 0;

    while (i <= listRange.length) {
        // After each remove, the index of the items is decreased by one
        listModel.remove(listRange[i] - nbOfRemovedItems);
        ++nbOfRemovedItems;
        i++;
    }
}

Upvotes: 2

Related Questions