If a selected index on a JList is clicked, I want it to de-select. In other words, clicking on the indices actually toggles their selection. Didn't look like this was supported, so I tried
list.addMouseListener(new MouseAdapter()
{
public void mousePressed(MouseEvent evt)
{
java.awt.Point point = evt.getPoint();
int index = list.locationToIndex(point);
if (list.isSelectedIndex(index))
list.removeSelectionInterval(index, index);
}
});
The problem here is that this is being invoked after JList has already acted on the mouse event, so it deselects everything. So then I tried removing all of JList's MouseListeners, adding my own, and then adding all of the default listeners back. That didn't work, since JList would reselect the index after I had deselected it. Anyway, what I eventually came up with is
MouseListener[] mls = list.getMouseListeners();
for (MouseListener ml : mls)
list.removeMouseListener(ml);
list.addMouseListener(new MouseAdapter()
{
public void mousePressed(MouseEvent evt)
{
java.awt.Point point = evt.getPoint();
final int index = list.locationToIndex(point);
if (list.isSelectedIndex(index))
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
list.removeSelectionInterval(index, index);
}
});
}
});
for (MouseListener ml : mls)
list.addMouseListener(ml);
... and that works. But I don't like it. Is there a better way?
Looking at the Example "ListSelectionModel: Enabling Toggle Selection Mode" here: http://java.sun.com/products/jfc/tsc/tech_topics/jlist_1/jlist.html
I have modified it slightly for multi-select list boxes (changed setSelectionInterval to addSelectionInterval) and eliminated a problem with re-selection if you click to de-select and move your mouse while the mouse is down (moved the gestureStarted check for both add and remove).
objList.setSelectionModel(new DefaultListSelectionModel() {
private static final long serialVersionUID = 1L;
boolean gestureStarted = false;
@Override
public void setSelectionInterval(int index0, int index1) {
if(!gestureStarted){
if (isSelectedIndex(index0)) {
super.removeSelectionInterval(index0, index1);
} else {
super.addSelectionInterval(index0, index1);
}
}
gestureStarted = true;
}
@Override
public void setValueIsAdjusting(boolean isAdjusting) {
if (isAdjusting == false) {
gestureStarted = false;
}
}
});