Reputation: 327
I have a standard JList
that will be changed while the program is running. In order to make life easier I have created a DefaultListModel
and assigned it to the JList
:
JList CharList = new JList();
DefaultListModel CharListModel = new DefaultListModel();
CharList.setModel(CharListModel);
I am able to load a file into the list, and later I can add items to the list like this:
File ChFile = new File (CharListFile);
FileReader freeder = new FileReader (ChFile);
BufferedReader breeder = new BufferedReader(freeder);
String line;
while((line=breeder.readLine())!=null)
{
int pos = CharList.getModel().getSize();
CharListModel.add(pos, line);
}
...
...
//and to add items..
int pos = CharList.getModel().getSize();
CharListModel.add(pos, NewCharName);
However, I need to be able to remove items from the list, and this is giving me some considerable trouble!
I have tried the most obvious way (Yes an item is selected, and I have already retrieved both the index and the string at that index):
CharListModel.removeElement(CharList.getSelectedValue());
However, this gives me a 'java.lang.ArrayIndexOutOfBoundsException: -1' error.
I have tried all of the permutations that you can see in the code below (Some are commented out but you get the idea):
DefaultListModel model = (DefaultListModel) CharList.getModel();//CharListModel;
int selectedIndex = CharList.getSelectedIndex();
if (selectedIndex != -1) {
//model.remove(selectedIndex);
//model.removeElement(CharList.getSelectedValue());
//model.removeElementAt(selectedIndex);
}
as well as a few other permutations as well:
CharListModel.removeElementAt(CharList.getSelectedIndex());
//or
CharListModel.remove(CharList.getSelectedIndex());
//or
CharList.remove(SelItemIndex);
In each case I get the same 'ArrayIndexOutOfBoundsException' error, even though the selected index is previously found with no trouble. And yes, I know I just said 'previously' so something could have changed things, but here is the code that runs directly before I try to remove the element:
int SelItemIndex = CharList.getSelectedIndex();
if(SelItemIndex == -1)
{
JOptionPane.showMessageDialog(null, "You have to select something!");
return;
}
String SelItem = CharList.getModel().getElementAt(SelItemIndex).toString();
//Create warning
final JComponent[] inputs = new JComponent[]
{
new JLabel("<html>Bla Bla " + SelItem + " Are you sure?</html>")
};
int n = JOptionPane.showConfirmDialog( null, inputs,"Deletion Confirmation Warning", JOptionPane.YES_NO_OPTION);
if( n == 1)
{
//Do not delete
return;
}
That is all there is before trying to remove the selected element.
For the life of me I don't know why this is not working! Am I missing something really silly here?
In the ActionPerformed
event of a JButton
I have used this code - The comments in the code explain why this is so confusing!:
DefaultListModel CharListModel = (DefaultListModel)CharList.getModel();
if( CharListModel.contains(CharList.getSelectedValue()) == true)
{
//Selected item is found
int selItemIndex = CharListModel.indexOf(CharList.getSelectedValue());
if(selItemIndex != -1)
{
//Selected item index is NOT -1 and is correct
CharListModel.remove(selItemIndex);
//Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: -1
}
else
{
//NEVER reached
JOptionPane.showMessageDialog(null, "OUCH!");
}
}
As you can see, the index of the selected item is correct right up to the point of removing it, whereupon I once again get the out of bounds exception. I also tried this in the same place but with the same results:
CharListModel.removeElement(CharList.getSelectedValue());
In an attempt to work out what is going on I have created a new DefaultListModel
, enumerated the old one, and put each name into the new model, except the one that I want to remove (Remember I can get the index, the object and the text, I just cant delete it).
This has worked and I now have a DefaultListModel
with the correct items in it, however, the moment that I try to CharList.setModel(NewModel);
I once again get the out of bounds exception.
This has got me pulling out hair! Can anyone offer any ideas to try?
Not really a resolution at all, but to work around this maddening problem I am using the method laid out above, where I create a copy of the list model, minus the item that I want to delete and then simply catch the exception when using setModel
, since the updated list model is added to the list just fine, and subsequent actions such as adding items etc. work okay, right up until I try to delete an item again anyway!
Thanks if you tried to help - and if you have any ideas about how to hunt down this problem, by all means post away!
regards
Max
Upvotes: 2
Views: 4280
Reputation: 68
I have the same problem, i fix this doing that:
Button Action
int index = mylist.getSelectedIndex();
MyObject = (MyObject) mylist.getSelectedValue();
int Size = mylistmodel.getSize();
if (index >= 0 && MyObject != null && Size > 0) {
modeloLista.removeElementAt(indice);
}
And.
listValueChanged
if (list.getSelectedValue() != null) {
your code..
}
Upvotes: 0
Reputation: 31
I had a similar problem. It turned out the error stemmed not from removing the element, but rather displaying the list. When implementing the
public void valueChanged(ListSelectionEvent e)
method, which updates the list on the screen, make sure to check if the model is null before you set the values. This is what caused the exceptions in my case.
Creating a list, removing from there, and then updating the model with the list is also a usable workaround.
Upvotes: 2
Reputation: 17
I have faced the same issue. It seems when the item is removed from the model, it gets removed from the array as well. Hence is messes up the array index.
As a work around, I moved the array contents into a List and remove the List contents from the model. Now it works fine for me.
Upvotes: 0
Reputation: 205785
For reference, I added the code below to this example. If it's not helpful, it may be a useful sscce for updating your question.
panel.add(new JButton(new AbstractAction("Remove") {
@Override
public void actionPerformed(ActionEvent e) {
int index = list.getSelectedIndex();
if (index != -1) {
model.remove(index);
}
}
}));
Upvotes: 3