我有一个现有的 JTable,我希望表的前 3 列不可移动。这意味着如果用户尝试拖动任何前 3 列的表格标题,它们将不会移动且根本不应该移动,但他们可以对其余列重新排序。
类似于下面一行的内容
myTable.getTableHeader().setReorderingAllowed(false);
但它仅适用于某些列,而不适用于所有列标题。
我尝试使用鼠标侦听器来解决此问题,因此当用户将鼠标悬停在前 3 列中的任何一列上时,我只需禁用整个表格的重新排序,如下所示,这样他们就无法拖动它。
myTable.getTableHeader().addMouseMotionListener(new MouseMotionListener(){
@Override
public void mouseMoved(MouseEvent me) {
int column = myTable.columnAtPoint(me.getPoint());
if(column < 3) myTable.getTableHeader().setReorderingAllowed(false);
else myTable.getTableHeader().setReorderingAllowed(true);
}
});
它确实阻止用户拖动前 3 列。但是,问题是用户仍然可以将其他列拖动到列顺序中的任何位置。他们可以将#8 列拖到#2 列之前,现在前 3 列不同。用户应该能够移动的最远列位置#8 就在列#3 之后。
实现这一目标的最佳方法是什么?
您可以覆盖列模型中的moveColumn和表头中的setDraggedColumn:
JTable table = /* ... */;
int lastFixedColumn = 2;
TableColumnModel columnModel = new DefaultTableColumnModel() {
private static final long serialVersionUID = 1;
@Override
public void moveColumn(int fromIndex,
int toIndex) {
if (fromIndex > lastFixedColumn) {
super.moveColumn(fromIndex,
Math.max(toIndex, lastFixedColumn + 1));
}
}
};
int numCols = table.getModel().getColumnCount();
for (int i = 0; i < numCols; i++) {
TableColumn column = new TableColumn(i);
column.setHeaderValue(table.getModel().getColumnName(i));
columnModel.addColumn(column);
}
JTableHeader header = new JTableHeader(columnModel) {
private static final long serialVersionUID = 1;
@Override
public void setDraggedColumn(TableColumn column) {
if (column == null ||
column.getModelIndex() > lastFixedColumn) {
super.setDraggedColumn(column);
}
}
};
table.setTableHeader(header);
table.setColumnModel(columnModel);