Question

I am trying to write a ListSelectionListener for a JList that knows which list item the user is selecting away from, and which list item the user is selecting to. So if a list has three items in it {Apple, Orange, Pear}, and the current selection is on Orange and the user selects Pear, then:

  • srcFruit is Orange; and
  • destFruit is Pear

Here's the code I have:

myList.addListSelectionListener(new ListSelectionListener() {
    public void valueChanged(ListSelectionEvent fruitSelectionEvent) {
        printSourceAndDestFruit(myList, fruitSelectionEvent);
    }
});

private void printSourceAndDestFruit(JList list, ListSelectionEvent event) {
    FruitVO srcFruit = (FruitVO)list.getModel().getElementAt(event.getFirstIndex());
    FruitVO destFruit = (FruitVO)list.getModel().getElementAt(event.getLastIndex());

    System.out.println("srcFruit = " + srcFruit.getName() + " and destFruit = " = destFruit.getName());
}

When the application loads and initializes the JList, there is no default selection. When I take the following actions:

  1. Click Orange
  2. Click Pear
  3. Click Orange again

Here's the print out I get:

srcFruit = Orange and destFruit = Pear
srcFruit = Orange and destFruit = Pear

Where am I going wrong here? Are getFirstIndex()/getLastIndex() buggy or just not the correct Swing methods to be using?

Here's the output I should be seeing:

srcFruit = Orange and destFruit = Pear
srcFruit = Pear and destFruit = Orange

So even though I made 3 selects (mouse clicks), since the first time I click Orange wasn't a change from one value to the next, I believe it is correct to not fire and call printSourceAndDestFruit. The I select Pear and it is correct in stating that srcFruit is Orange and that destFruit is Pear. But when I click back to Orange the 2nd println should have srcFruit as Pear and destFruit as Orange. Why doesn't it?!?!

Thanks in advance!

Was it helpful?

Solution

The first and last index are not what you think they are. Here's what the javadoc says:

getFirstIndex()

Returns the index of the first row whose selection may have changed.

getLastIndex()

Returns the index of the last row whose selection may have changed.

So, since the selection of pear and orange changes at each click, and since pear is after orange in the list, getFirstIndex() always returns Orange and getLastIndex() always returns Pear.

If you want to compare the new selection with the last one, then keep the last selection in some member variable, and compare it with the new selection each time the selection changes, and getValueIsAdjusting() returns false.

OTHER TIPS

The reason that selection is in the order Orange, Pear is that the DefaultListSelectionModel calls fireValueChanged solely based on the items index location in the ListModel rather than the new selection index.

This related bug report asked a similar question but shows that this was normal behavior and showed that you could add a workaround by using:

FruitVO srcFruit = (FruitVO)list.getModel().getElementAt(list.getMinSelectionIndex());
FruitVO destFruit = (FruitVO)list.getModel().getElementAt(list.getMaxSelectionIndex());
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top