在我的JTable中,我已经在更新期间实现了选择保留逻辑。不幸的是我觉得我遇到过某种错误。 JTable由后台线程更新,后台线程获取新数据并从表模型中添加/修改/删除它。
只有当用户正在拖动鼠标以选择表格中的行时,执行更新时,问题才会出现。让我最困惑的是:
为什么会发生这种情况的任何线索?
这是我正在谈论的代码的精简版。
我正在使用手动同步的TreeSet
来更新后台线程中的数据(请参阅update
)。当我完成后,我调用atomicSwapData
创建将由getValueAt
使用的数组。
在updateTable中,你可以看到我是如何实现我之前讨论的选择保留逻辑的。如您所见,我尝试使用EventQueue.invokeLater
方法,但问题仍然存在。请注意,任何线程都可以调用所有方法,而不仅仅是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);
}
}
});
}
}
答案 0 :(得分:1)
作为参考,此example会使用TableModel
从后台线程不断更新EventQueue.invokeLater()
。它没有表现出你描述的异常现象。
答案 1 :(得分:0)
jtable的标准绘画是从上到下,这可能是它在一个方向但不在另一个方向上打破的原因。
你必须更加清晰,并定义你的“休息”
它只是选择错误的选择吗?那么你应该能够通过在更新触发后强制你的表进行完全重绘来修复它