问题描述
我需要检测用户何时对 JTable
的列重新排序,以便保留和恢复该信息。根据 JavaDocs,将 propertychangelistener
添加到表列应该就足够了,例如
JTable t = ...;
TableColumn keysColumn = t.getColumnModel().getColumn(0);
TableColumn valuesColumn = t.getColumnModel().getColumn(1);
keysColumn.addPropertychangelistener(new Propertychangelistener {
public void propertyChange(PropertyChangeEvent e) {
System.out.println("PROPERTY: " + e.getPropertyName());
}
});
然而,虽然我收到 width
和 preferredWidth
的更新,但重新排列列并不会触发任何可观察到的内容。我期待看到 modelIndex
的更新。做错了什么?
Linux 上的 OpenJDK 11,尝试了不同的外观。
解决方法
所以 modelIndex
的 TableColumn
永远不会改变,因此没有属性改变。要观察运动,必须监听 TableColumnModel
的 columnMoved
并过滤 e.getFromIndex != e.getToIndex
是视图索引,然后将它们映射回模型索引。 “如此简单”:-/
在 Scala 中
val tcm = t.getColumnModel
tcm.addColumnModelListener(new TableColumnModelListener {
private def mkMap() = Seq.tabulate(t.getColumnCount)(t.convertColumnIndexToModel)
private var viewToModel = mkMap()
override def columnMoved(e: TableColumnModelEvent): Unit = {
val viewFrom = e.getFromIndex
val viewTo = e.getToIndex
if (viewFrom != viewTo) {
val modelFrom = viewToModel(viewFrom)
val modelTo = viewToModel(viewTo )
println(s"columnMoved: drag column $modelFrom from pos $viewFrom to $viewTo")
viewToModel = mkMap()
assert (viewToModel(viewTo) == modelFrom)
}
}
override def columnAdded (e: TableColumnModelEvent ): Unit = ()
override def columnRemoved (e: TableColumnModelEvent ): Unit = ()
override def columnMarginChanged (e: ChangeEvent ): Unit = ()
override def columnSelectionChanged (e: ListSelectionEvent ): Unit = ()
})