JDK-4816818 : JList.getSelectedValue() does not handle items removed from the model
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 1.4.1
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2003-02-11
  • Updated: 2003-02-13
  • Resolved: 2003-02-13
Related Reports
Duplicate :  
Relates :  
Description

Name: pa48320			Date: 02/11/2003

If the last item in a Jlist is selected and an item gets deleted from a listModel, in the intervalRemoved method of the ListDataListener, an exception will be thrown if getSelectedValue() is called on the Jlist. The exception is the following:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2 >= 2
        at java.util.Vector.elementAt(Vector.java:427)
        at javax.swing.DefaultListModel.getElementAt(DefaultListModel.java:70)
        at javax.swing.JList.getSelectedValue(JList.java:1809)
        at JListSelectedValueTest.intervalRemoved(JListSelectedValueTest.java:36)
        at javax.swing.AbstractListModel.fireIntervalRemoved(AbstractListModel.java:160)
        at javax.swing.DefaultListModel.removeElementAt(DefaultListModel.java:313)
        at JListSelectedValueTest.<init>(JListSelectedValueTest.java:23)
        at JListSelectedValueTest.main(JListSelectedValueTest.java:41)

Here is a sample test app that demonstrates the problem:

import javax.swing.*;
import javax.swing.event.*;
public class JListSelectedValueTest extends JFrame implements ListDataListener {
   protected JList list;
   public JListSelectedValueTest()
   {
      DefaultListModel model = new DefaultListModel();
      model.addElement("one");
      model.addElement("two");
      model.addElement("three");

      list = new JList(model);
      JScrollPane pane = new JScrollPane(list);
      getContentPane().add(pane);

      setSize(400, 400);
      model.addListDataListener(this);
      list.setSelectedIndex(list.getModel().getSize() - 1);
      model.removeElement(0);
   }

   public void contentsChanged(ListDataEvent e)
   {
   }

   public void intervalAdded(ListDataEvent e)
   {
   }

   public void intervalRemoved(ListDataEvent e)
   {
      System.out.println(" list.getSelectedValue()="+(list.getSelectedValue()));
   }

   public static void main(String[] args)
   {
      JListSelectedValueTest test = new JListSelectedValueTest();
      test.setVisible(true);
   }
}

======================================================================

Comments
EVALUATION Name: apR10133 Date: 02/13/2003 When we remove the first element from the list model it removes this element from the elements vector and then notify ListDataListeners. The selection model is apdated after the BasicListUI.ListDataHandler handle the appropriate event. But as the application ListDataListener is added after the plaf's one it will get the event first, because the listenera are notified in the backward order. As the result the selection model is not updated yet when the test try to access it. We recommend using an invokeLater to call the selection related methods. That way you will know that we have updated the selection model. Additionally, there is a rfe against beans (#4178930) to add ordering to event listeners so that Swing's listeners could be updated first, then application listeners. ###@###.### ======================================================================
24-08-2004