JDK-4338140 : DefaultListSelectionModel.insertIndexInterval() should update lead/anchorIndex.
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 1.2.2
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: generic
  • CPU: generic
  • Submitted: 2000-05-15
  • Updated: 2004-04-26
  • Resolved: 2004-04-26
Related Reports
Duplicate :  
Relates :  
Description

Name: stC104175			Date: 05/15/2000


Symantec Java! JustInTime Compiler Version 4.00.006(x) for JDK 1.2 (Symantec GC)

Copyright (C) 1996-99 Symantec Corporation

java version "1.2.2.Symc"
Classic VM (build 1.2.2.Symc, native threads, symantec gc, symcjit)


DefaultListSelectionModel.insertIndexInterval() should update leadIndex and
anchorIndex.
That is, ...

public void insertIndexInterval(int index, int length, boolean before)
{
    ....

    // Following codes should be appended.
    if (anchorIndex >= insMinIndex)
        anchorIndex += length;
    if (leadIndex >= insMinIndex)
        leadIndex += length;
}

Also

Symantec Java! JustInTime Compiler Version 4.00.006(x) for JDK 1.2 (Symantec GC)

Copyright (C) 1996-99 Symantec Corporation

java version "1.2.2.Symc"
Classic VM (build 1.2.2.Symc, native threads, symantec gc, symcjit)


DefaultListSelectionModel.removeIndexInterval() should update leadIndex and
anchorIndex.
That is, ...

public void removeIndexInterval(int index0, int index1)
{
    ....

    // Following codes should be appended.
    if (anchorIndex > rmMaxIndex)
        anchorIndex -= gapLength;
    else if (anchorIndex >= rmMinIndex)
        anchorIndex = -1;
    if (leadIndex > rmMaxIndex)
        leadIndex -= gapLength;
    else if (leadIndex >= rmMinIndex)
        leadIndex = -1;
}
(Review ID: 104869) 
======================================================================

Name: apR10133			Date: 12/05/2001


Here is the testcase so show the problem.

------------------------- test.java -----------------------
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class test {
    
    JList lst;
    DefaultListSelectionModel lsm;
    DefaultListModel lm;
    JTextField first, length;

    public test() {
	JFrame fr = new JFrame("Test");
	fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        String [] data = {"null", "one", "two", "three",
			  "four", "five", "six", "seven"};
        lst = new JList(data);
        JScrollPane sp = new JScrollPane(lst);
	lm = new DefaultListModel();
	for (int i=0; i<10; i++) {
	    lm.addElement("Element "+i);
	} 
	lst.setModel(lm);
	lsm = new DefaultListSelectionModel();
	lst.setSelectionModel(lsm);
	lst.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
        fr.getContentPane().add(sp);

	JPanel p = new JPanel();
	fr.getContentPane().add(p, BorderLayout.SOUTH);
	p.setLayout(new GridLayout(2,4));

	first = new JTextField("1");
	p.add(new JLabel("Start with"));
	p.add(first);
	length = new JTextField("1");
	p.add(new JLabel("Length"));
	p.add(length);

	JButton bt = new JButton("Print");
	p.add(bt);
	bt.addActionListener(new ActionListener() {
		public void actionPerformed(ActionEvent e) {
		    System.out.println("A:  "+lst.getAnchorSelectionIndex());
                    System.out.println("L:  "+lst.getLeadSelectionIndex());
		}
	    });

	JButton ins = new JButton("Insert");
	p.add(ins);
	ins.addActionListener(new ActionListener() {
		public void actionPerformed(ActionEvent e) {
		    try {
			int i0 = Integer.parseInt(first.getText());
			int len = Integer.parseInt(length.getText());
			for (int i=0; i<len; i++) {
			    lm.insertElementAt("Element...", i0+i);
			}
			lst.updateUI();
		    } catch (Exception exc) {
			exc.printStackTrace();
		    }
		}
	    });

	JButton rem = new JButton("Remove");
	p.add(rem);
	rem.addActionListener(new ActionListener() {
		public void actionPerformed(ActionEvent e) {
		    try {
			int i0 = Integer.parseInt(first.getText());
			int len = Integer.parseInt(length.getText());
			lm.removeRange(i0, i0+len-1);
			lst.updateUI();
		    } catch (Exception exc) {
			exc.printStackTrace();
		    }
		}
	    });

	fr.setSize(400,200);
	fr.setVisible(true);
    }
    

    public static void main(String[] argv) {
	test b = new test();
    }
}
----------------------------------------------------------- 

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

Comments
SUGGESTED FIX Name: apR10133 Date: 12/05/2001 ------- DefaultListSelectionModel.java ------- *** /tmp/sccs.U3aOhs Wed Dec 5 18:29:56 2001 --- DefaultListSelectionModel.java Wed Dec 5 18:26:38 2001 *************** *** 518,527 **** /* Initialize the newly inserted indices. */ ! boolean setInsertedValues = value.get(index); for(int i = insMinIndex; i <= insMaxIndex; i++) { setState(i, setInsertedValues); } fireValueChanged(); } --- 518,544 ---- /* Initialize the newly inserted indices. */ ! boolean setInsertedValues; ! if (getSelectionMode() == SINGLE_SELECTION) { ! setInsertedValues = false; ! } else { ! setInsertedValues = value.get(index); ! } for(int i = insMinIndex; i <= insMaxIndex; i++) { setState(i, setInsertedValues); } + + int anchor = getAnchorSelectionIndex(); + if (anchor >= insMinIndex) { + anchor = anchor+length; + } + + int lead = getLeadSelectionIndex(); + if (lead >= insMinIndex) { + lead = lead+length; + } + + updateLeadAnchorIndices(lead, anchor); fireValueChanged(); } *************** *** 544,549 **** --- 561,601 ---- for(int i = rmMinIndex; i <= maxIndex; i++) { setState(i, value.get(i + gapLength)); } + + int anchor = getAnchorSelectionIndex(); + int lead = getLeadSelectionIndex(); + int newAnchor = anchor; + int newLead = lead; + + if (anchor != -1) { + if (anchor > rmMaxIndex) + newAnchor = anchor-gapLength; + else if (anchorIndex >= rmMinIndex) { + if (lead > rmMaxIndex) { + newAnchor = rmMinIndex; + } else if (lead >= rmMinIndex || lead==-1) { + newAnchor = -1; + } else { + newAnchor = rmMinIndex-1; + } + } + } + + if (lead != -1) { + if (lead > rmMaxIndex) + newLead = lead-gapLength; + else if (leadIndex >= rmMinIndex) { + if (anchor > rmMaxIndex) { + newLead = rmMinIndex; + } else if (anchor >= rmMinIndex || anchor==-1) { + newLead = -1; + } else { + newLead = rmMinIndex-1; + } + } + } + + updateLeadAnchorIndices(newLead, newAnchor); fireValueChanged(); } ###@###.### ======================================================================
11-06-2004

EVALUATION Name: apR10133 Date: 12/05/2001 See the description for the testcase which shows the problem. The suggestions in the description are inaccurate. I would suggest not to change the lead/anchor indices directly, but use the updateLeadAnchorIndices() for this purpose. As for removeIndexInterval(), I would suggest to use the following algorithm: lead < m m <= lead <= M lead > M ------------------------------------------------------------------- anchor < m nothing lead=m-1 lead=lead-length m< anchor <M anchor=m-1 ancho=-1 lead=lead-length lead=-1 anchor > M anchor= anchor= anchor= anchor-length anchor-length anchor-length lead=m lead=lead-length ------------------------------------------------------------------- Where "m" is a start index of the removed interval and M = m+length (i.e. last index of the removed interval). Also, the insertIndexInterval() method doesn't take into account the selection model, but the SINGLE_SELECTION model requires special handling. ###@###.### ====================================================================== This was in fact fixed for tiger. Most of the work was done under bug id 4803311. It was then tweaked in the fix for 4905083. ###@###.### 2004-04-26
26-04-2004