Java:根据枚举中的列对 JTable 进行排序
Java: order a JTable according to columns from enum
我有一个 JTable,其中多个列包含来自如下枚举的数字:
public static enum IMPORT_CONF_OPERATION_RESULT {
OK(0, "OK"),
ERROR(1, "ERROR"),
WAITING(2, "WAITING");
/* ... */
}
所以,我需要重写 table 模型循环遍历枚举值的方法 getValueAt()
,以便解码和 return 每行对应的字符串,在数据库中来自哪个数据,存储数值。
现在,如果用户点击对应的 header 列,行将根据数值排序,但我想按字母顺序排列。我应该覆盖 table 模型的 sort()
方法吗?通过枚举值循环这么多次来获得低效的描述不是吗?它会减慢 table 渲染速度吗?
更新
这可能是根据 STaefi 建议的解决方案,在我的扩展 DefaultTableModelField
:
中
@Override
public void sort(int col, boolean ascendest) {
ColumnProperties columnProperties = this.mapColumn.get(col);
if (COLUMN_NAME_ENTITY.equals(columnProperties.getInfo()) ||
COLUMN_OPERATION_TYPE.equals(columnProperties.getInfo()) ||
COLUMN_OPERATION_RESULT.equals(columnProperties.getInfo()) ||
COLUMN_ELABORATION_TYPE.equals(columnProperties.getInfo()) ||
COLUMN_EVENT_STATE.equals(columnProperties.getInfo())) {
Collections.sort((List<TableImportConfEvent>)this.value, new EnumColumnSorter(ascendest, columnProperties.getInfo()));
this.fireTableDataChanged();
}
else {
super.sort(col, ascendest);
}
}
private class EnumColumnSorter implements Comparator<TableImportConfEvent> {
private int ascending;
private String columnName;
public EnumColumnSorter(boolean ascendest, String columnName) {
this.ascending = ascendest ? 1 : -1;
this.columnName = columnName;
}
@Override
public int compare(TableImportConfEvent o1, TableImportConfEvent o2) {
String decodedString1 = "";
String decodedString2 = "";
if (COLUMN_NAME_ENTITY.equals(this.columnName)) {
decodedString1 = getEntityName(o1.getEntityType());
decodedString2 = getEntityName(o2.getEntityType());
}
else if (COLUMN_OPERATION_TYPE.equals(this.columnName)) {
decodedString1 = getOperationName(o1.getOperationType());
decodedString2 = getOperationName(o2.getOperationType());
}
else if (COLUMN_OPERATION_RESULT.equals(this.columnName)) {
decodedString1 = getResultName(o1.getOperationResult());
decodedString2 = getResultName(o2.getOperationResult());
}
else if (COLUMN_ELABORATION_TYPE.equals(this.columnName)) {
decodedString1 = getResultName(o1.getOperationResult());
decodedString2 = getResultName(o2.getOperationResult());
}
else if (COLUMN_EVENT_STATE.equals(this.columnName)) {
decodedString1 = getStateName(o1.getEventState());
decodedString2 = getStateName(o2.getEventState());
}
return (decodedString1.compareTo(decodedString2)) * this.ascending;
}
}
为避免遍历每一行的枚举值,您可能需要创建一个 static final HashMap<Integer,IMPORT_CONF_OPERATION_RESULT>
以将值映射缓存到相应的标签,并在枚举内的静态块中对其进行初始化。然后你可以有一个public static String getLabelByValue(int value)
来使用缓存并且避免O(n)
每次查找标签。
为了控制排序顺序和排序操作,您可能希望在 TableRowSorter
之后进行,但是当您为模型覆盖 getValueAt
时,默认排序应该就足够了。另一种方法是在 table 模型中使用自定义 Comparator
来管理排序逻辑。
我有一个 JTable,其中多个列包含来自如下枚举的数字:
public static enum IMPORT_CONF_OPERATION_RESULT {
OK(0, "OK"),
ERROR(1, "ERROR"),
WAITING(2, "WAITING");
/* ... */
}
所以,我需要重写 table 模型循环遍历枚举值的方法 getValueAt()
,以便解码和 return 每行对应的字符串,在数据库中来自哪个数据,存储数值。
现在,如果用户点击对应的 header 列,行将根据数值排序,但我想按字母顺序排列。我应该覆盖 table 模型的 sort()
方法吗?通过枚举值循环这么多次来获得低效的描述不是吗?它会减慢 table 渲染速度吗?
更新
这可能是根据 STaefi 建议的解决方案,在我的扩展 DefaultTableModelField
:
@Override
public void sort(int col, boolean ascendest) {
ColumnProperties columnProperties = this.mapColumn.get(col);
if (COLUMN_NAME_ENTITY.equals(columnProperties.getInfo()) ||
COLUMN_OPERATION_TYPE.equals(columnProperties.getInfo()) ||
COLUMN_OPERATION_RESULT.equals(columnProperties.getInfo()) ||
COLUMN_ELABORATION_TYPE.equals(columnProperties.getInfo()) ||
COLUMN_EVENT_STATE.equals(columnProperties.getInfo())) {
Collections.sort((List<TableImportConfEvent>)this.value, new EnumColumnSorter(ascendest, columnProperties.getInfo()));
this.fireTableDataChanged();
}
else {
super.sort(col, ascendest);
}
}
private class EnumColumnSorter implements Comparator<TableImportConfEvent> {
private int ascending;
private String columnName;
public EnumColumnSorter(boolean ascendest, String columnName) {
this.ascending = ascendest ? 1 : -1;
this.columnName = columnName;
}
@Override
public int compare(TableImportConfEvent o1, TableImportConfEvent o2) {
String decodedString1 = "";
String decodedString2 = "";
if (COLUMN_NAME_ENTITY.equals(this.columnName)) {
decodedString1 = getEntityName(o1.getEntityType());
decodedString2 = getEntityName(o2.getEntityType());
}
else if (COLUMN_OPERATION_TYPE.equals(this.columnName)) {
decodedString1 = getOperationName(o1.getOperationType());
decodedString2 = getOperationName(o2.getOperationType());
}
else if (COLUMN_OPERATION_RESULT.equals(this.columnName)) {
decodedString1 = getResultName(o1.getOperationResult());
decodedString2 = getResultName(o2.getOperationResult());
}
else if (COLUMN_ELABORATION_TYPE.equals(this.columnName)) {
decodedString1 = getResultName(o1.getOperationResult());
decodedString2 = getResultName(o2.getOperationResult());
}
else if (COLUMN_EVENT_STATE.equals(this.columnName)) {
decodedString1 = getStateName(o1.getEventState());
decodedString2 = getStateName(o2.getEventState());
}
return (decodedString1.compareTo(decodedString2)) * this.ascending;
}
}
为避免遍历每一行的枚举值,您可能需要创建一个 static final HashMap<Integer,IMPORT_CONF_OPERATION_RESULT>
以将值映射缓存到相应的标签,并在枚举内的静态块中对其进行初始化。然后你可以有一个public static String getLabelByValue(int value)
来使用缓存并且避免O(n)
每次查找标签。
为了控制排序顺序和排序操作,您可能希望在 TableRowSorter
之后进行,但是当您为模型覆盖 getValueAt
时,默认排序应该就足够了。另一种方法是在 table 模型中使用自定义 Comparator
来管理排序逻辑。