Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4223100

JList.getSelectedIndices() returns bad values

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Duplicate
    • Icon: P4 P4
    • None
    • 1.2.0
    • client-libs
    • x86, sparc
    • solaris_2.6, windows_nt



      Name: dbT83986 Date: 03/23/99


      This example shows the problem. Follow the following steps,
      1) select an item in the list.
      2) Click the button to remove all items
      3) Click the button to report the number of selected items.

      As you can see, the value returned is 1 and not zero.

      There are several ways to fix the problem. One way is
      to have the ListSelectionModel connected to the ListModel so
      that the selection model can tell when an index is out of range.
      However, this solution doesn't seem to follow the class
      architecture you are using.

      Another solution is to change the getSelectedIndices() method
      in JList to check for an index that is out of range.

      By checking to see if iMin <= size we can ensure that the
      minimum value is a valid index. This covers the max out of
      range since iMin is <= iMax.

      Old Method:
          public int[] getSelectedIndices() {
              ListSelectionModel sm = getSelectionModel();
              int iMin = sm.getMinSelectionIndex();
              int iMax = sm.getMaxSelectionIndex();

              if ((iMin < 0) || (iMax < 0) || iMin > ) {
                  return new int[0];
              }

              int[] rvTmp = new int[1+ (iMax - iMin)];
              int n = 0;
              for(int i = iMin; i <= iMax; i++) {
                  if (sm.isSelectedIndex(i)) {
                      rvTmp[n++] = i;
                  }
              }
              int[] rv = new int[n];
              System.arraycopy(rvTmp, 0, rv, 0, n);
              return rv;
          }
      New Method:
           public int[] getSelectedIndices() {
              ListSelectionModel sm = getSelectionModel();
              ListModel m = getModel(); //New Line
              int iMin = sm.getMinSelectionIndex();
              int iMax = sm.getMaxSelectionIndex();
              int size = m.getSize(); //New Line
              /* Altered statement */
              if ((iMin < 0) || (iMax < 0) || iMin >= size) {
                  return new int[0];
              }
              /* End altered statement */
              int[] rvTmp = new int[1+ (iMax - iMin)];
              int n = 0;
              for(int i = iMin; i <= iMax; i++) {
                  if (sm.isSelectedIndex(i)) {
                      rvTmp[n++] = i;
                  }
              }
              int[] rv = new int[n];
              System.arraycopy(rvTmp, 0, rv, 0, n);
              return rv;
          }
      Example source code:

      import java.awt.BorderLayout;
      import java.awt.event.*;
      import java.util.Vector;

      import javax.swing.*;
      import javax.swing.event.*;

      public class SunTest7 {
      public static void main(String[] args) {
      JFrame f = new JFrame("Selecting problem");
      f.addWindowListener( new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
      System.exit(0);
      }
      });
      f.setSize(400,300);
      JPanel panel = new JPanel(new BorderLayout());
      final Model model = new Model();
      final JList list = new JList( (ListModel)model );
      //list.setCellRenderer(new NormalRenderer());
      panel.add(new JScrollPane(list),BorderLayout.CENTER);
      JPanel p = new JPanel();
      JButton b = new JButton("Print Selected Item Count");
      b.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
      System.out.println(list.getSelectedIndices().length);
      }
      });
      p.add(b);

      b = new JButton("Remove All Items");
      b.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
      int[] i = list.getSelectedIndices();
      System.out.println(i.length);
      if (i.length > 0) {
      int index = list.getSelectedIndex();
      model.removeAllElements();
      }
      }
      });
      p.add(b);
      panel.add(p,BorderLayout.SOUTH);
      f.getContentPane().add(panel);
      System.out.println(list.getSelectionForeground());
      System.out.println(list.getSelectionBackground());
      f.setVisible(true);
      }
      private final static class Model extends Vector implements ListModel {
      private EventListenerList listeners;
      public Model () {
      listeners = new EventListenerList();
      addElement("Pickles");
      addElement("Bananas");
      addElement("Grapefruit");
      }
      public int getSize() {
      return size();
      }
      public Object getElementAt(int index) {
      if (index < getSize())
      return elementAt(index);
      else
      return null;
      }
      public void removeAllElements() {
      super.removeAllElements();
      fireListDataEvent(new ListDataEvent(this,ListDataEvent.CONTENTS_CHANGED,-1,-1));
      }
      public void addListDataListener(ListDataListener l) {
      listeners.add(ListDataListener.class,l);
      }
      public void removeListDataListener(ListDataListener l) {
      listeners.remove(ListDataListener.class,l);
      }
      private void fireListDataEvent(ListDataEvent e) {
      int type = e.getType();
      if (type == ListDataEvent.CONTENTS_CHANGED)
      fireContentsChanged(e);
      else if (type == ListDataEvent.INTERVAL_ADDED)
      fireIntervalAdded(e);
      else
      fireIntervalRemoved(e);
      }
      private void fireContentsChanged(ListDataEvent e) {
      Object[] listenerList = listeners.getListenerList();
      for (int i = listenerList.length - 1; i > 0; i--)
      ((ListDataListener)listenerList[i]).contentsChanged(e);
      }
      private void fireIntervalAdded(ListDataEvent e) {
      Object[] listenerList = listeners.getListenerList();
      for (int i = listenerList.length - 1; i > 0; i--)
      ((ListDataListener)listenerList[i]).intervalAdded(e);
      }
      private void fireIntervalRemoved(ListDataEvent e) {
      Object[] listenerList = listeners.getListenerList();
      for (int i = listenerList.length - 1; i > 0; i--)
      ((ListDataListener)listenerList[i]).intervalRemoved(e);
      }
      }
      }
      (Review ID: 55585)
      ======================================================================

      Name: dbT83986 Date: 04/16/99


      uname -a
      SunOS monkfish.sailfish.com 5.6 Generic_105181-09 sun4u sparc SUNW,Ultra-1
      java -version
      java version "1.2"
      Solaris VM (build Solaris_JDK_1.2_01, native threads, sunwjit)

      In JList or JTable which use ListSelectionModel (for items and rows)
      respectively, the selection is not properly cleared when the last
      item is deleted from the model.
      Build any JTable (with DefaultTableModel so that you can delete rows)
      or any JList.
      Add a button to your panel that deletes an item from JList or a row from your
      JTable's defaulttableModel.



      When they become visible on the screen, select an item in JList or
      a row in JTable by clicking on it and press the button to delete the entry.
      Keep deleting until you get rid of all of them, but keep selectin an item
      or row by clicking each time before you delete it.
      When you delete your last entry, query the selectionModel for minSelectedIndex
      or check if isSelectionEmpty. In both cases, the return value will
      indicate that there is still a valid selection while there are NO
      items in the JTable or JList.
      I have to do model.clearSelection() explicitly each time I remove
      an item to make sure this lingering and invalid selection does not affect my logic.
      ======================================================================

            sswingtrsunw Swingtraq Swingtraq (Inactive)
            dblairsunw Dave Blair (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: