Java: Swing: JTable and TableModel: Selection
JTable.changeSelection is broken because it relies on the stupid behaviour of DefaultListSelectionModel to change the selection from setLeadSelectionIndex(). That makes independent handling of selection and focus/anchor impossible. See FTable.java.
It has to be done with a MouseListener on the column header. Unfortunately it cannot be done totally LAF-independent, you have to make some assumptions about the behaviour of keyboard modifiers (changeSelection cannot be used, it wants a cell and not a whole row/column). The following is just a suggestion:
public void mouseClicked(MouseEvent e)
{
JTableHeader header = table.getTableHeader();
TableColumnModel columns = header.getColumnModel();
if (!columns.getColumnSelectionAllowed())
return;
int column = header.columnAtPoint(e.getPoint());
if (column == -1)
return;
int count = table.getRowCount();
if (count != 0)
table.setRowSelectionInterval(0, count - 1);
ListSelectionModel selection = columns.getSelectionModel();
if (e.isShiftDown())
{
int anchor = selection.getAnchorSelectionIndex();
int lead = selection.getLeadSelectionIndex();
if (anchor != -1)
{
boolean old = selection.getValueIsAdjusting();
selection.setValueIsAdjusting(true);
boolean anchorSelected = selection.isSelectedIndex(anchor);
if (lead != -1)
{
if (anchorSelected)
selection.removeSelectionInterval(anchor, lead);
else
selection.addSelectionInterval(anchor, lead);
// The latter is quite unintuitive.
}
if (anchorSelected)
selection.addSelectionInterval(anchor, column);
else
selection.removeSelectionInterval(anchor, column);
selection.setValueIsAdjusting(old);
}
else
selection.setSelectionInterval(column, column);
}
else if (e.isControlDown())
{
if (selection.isSelectedIndex(column))
selection.removeSelectionInterval(column, column);
else
selection.addSelectionInterval(column, column);
}
else
{
selection.setSelectionInterval(column, column);
}
}For dragging it gets still more complicated (and interferes with column moving).
(C) 2001-2009 Christian Kaufhold (swing@chka.de)