Reputation: 30301
In my JTable I have already implemented the selection-preserving logic during updates. Unfortunately I think I have come across some kind of bug. The JTable is updated by a background thread that fetches new data and adds/modifies/removes it from the table model.
The problem shows itself only when an update is performed while the user is dragging the mouse to select rows in the table. What puzzles me the most is that:
Any clues as why this might be happening?
This is a trimmed down version of the code I'm talking about.
I am using a manually synchronized TreeSet
to update the data in background threads (see update
). When I'm done, I invoke atomicSwapData
that creates the array that will be used by getValueAt
.
In updateTable you can see how I implemented the selection-preserving logic I was talking about before. As you can see I tried using the EventQueue.invokeLater
method but the problem still appears. Please note that all methods may be called by any thread, not just the EDT.
class MyDataModel extends AbstractTableModel {
TreeSet<MyDataItem> ht = new TreeSet<MyDataItem>();
MyDataItem[] _ht = MyDataItem.emptyArray();
public Object getValueAt(int row, int col) {
MyDataItem qdi;
synchronized (_ht) {
qdi = _ht[row];
}
// return one of the members of qdi, based on col
}
public void update(String qm, Collection<MyDataItem> toAdd) {
HashSet<MyDataItem> toDrop = new HashSet<MyDataItem>();
synchronized (ht) {
// do something with ht
}
swapData();
}
private void swapData() {
EventQueue.invokeLater(new Runnable() {
public void run() {
synchronized(_ht) {
MyDataItem[] tmp = ht.toArray(MyDataItem.emptyArray());
synchronized(tmp) {
_ht = tmp;
}
}
}
});
updateTable();
}
private void updateTable() {
EventQueue.invokeLater(new Runnable() {
public void run() {
synchronized (_ht) {
int[] rowIndices = table.getSelectedRows();
fireTableDataChanged();
for (int row: rowIndices)
table.addRowSelectionInterval(row, row);
}
}
});
}
}
Upvotes: 0
Views: 519
Reputation: 205785
For reference, this example continually updates the TableModel
from a background thread using EventQueue.invokeLater()
. It does not exhibit the anomaly you describe.
Upvotes: 1
Reputation: 5798
standard painting for a jtable is from top to bottom this might be a reason why it breaks in one direction but not the other.
You will have to be abit more clear and define your 'breaks'
Does it just paints the selection wrong ? then you should be able to fix it by forcing your table to do a full repaint after the update fires
Upvotes: 0