我有以下代码用于 RowSorterListener
。这样做的目的是在不影响任何其他列的情况下对列进行排序。
import javax.swing.event.RowSorterListener;
import javax.swing.event.RowSorterEvent;
import javax.swing.JTable;
import javax.swing.RowSorter.SortKey;
import java.util.List;
import java.util.Arrays;
public class UnrelateData implements RowSorterListener {
JTable table;
int columnSorted = -1;
Object[][] dataStore;
public UnrelateData(JTable table) {
this.table = table;
}
@Override
public void sorterChanged(RowSorterEvent e)
{
if(e.getType() == RowSorterEvent.Type.SORT_ORDER_CHANGED) {
List<SortKey> keys = e.getSource().getSortKeys();
for (SortKey key : keys) {
if (key.getColumn() == -1) {
columnSorted = -1;
break;
} else {
columnSorted = key.getColumn();
break;
}
}
dataStore = getData();
}
if(e.getType() == RowSorterEvent.Type.SORTED) {
List<SortKey> keys = e.getSource().getSortKeys();
for (SortKey key : keys) {
if (key.getColumn() == -1) {
columnSorted = -1;
break;
} else {
columnSorted = key.getColumn();
break;
}
}
for(int i = 0; i < table.getColumnCount(); i++) {
if(i != columnSorted && columnSorted != -1) {
for (int j = 0; j < table.getRowCount(); j++) {
table.setValueAt(dataStore[i][j], j, i);
}
}
}
}
}
private Object[][] getData() {
int columnCount = table.getColumnCount();
int rowCount = table.getRowCount();
Object[][] tempData = new Object[columnCount][rowCount];
for(int i = 0; i < columnCount; i++) {
for(int j = 0; j < rowCount; j++) {
tempData[i][j] = table.getValueAt(j, i);
}
}
return tempData;
};
}
这很好用。但是,有一个主要故障。如果一列被移动并且我尝试对一列进行排序,它不会正确地对该列进行排序。相反,它会在移动列的原始位置错误地对该列进行排序。
虽然它应该看起来像(“第 1 列”和“第 2 列”保持未排序)
有人能解释为什么会发生这种情况以及如何解决吗?
注意:我不想使用 JTableHeader.reorderingAllowed(false)
编辑
我在我的代码中添加了以下 for 循环并尝试了不同的变体,但它似乎不起作用
尝试 1
if(e.getType() == RowSorterEvent.Type.SORTED) {
int[] actualColumn = new int[table.getColumnCount()];
for(int i = 0; i<table.getColumnCount(); i++){
actualColumn[i] = table.convertColumnIndexToModel(i);
}
int[] actualRow = new int[table.getRowCount()];
for(int i = 0; i<table.getRowCount(); i++){
actualRow[i] = table.convertRowIndexToModel(i);
}
List<SortKey> keys = e.getSource().getSortKeys();
for (SortKey key : keys) {
if (key.getColumn() == -1) {
columnSorted = -1;
break;
} else {
columnSorted = key.getColumn();
break;
}
}
for(int i = 0; i < table.getColumnCount(); i++) {
if(i != columnSorted && columnSorted != -1) {
for (int j = 0; j < table.getRowCount(); j++) {
table.setValueAt(dataStore[i][j], actualRow[j], actualColumn[i]);
}
}
}
}
尝试 2
private Object[][] getData() {
int columnCount = table.getColumnCount();
int rowCount = table.getRowCount();
int[] actualColumn = new int[columnCount];
for(int i = 0; i<table.getColumnCount(); i++){
actualColumn[i] = table.convertColumnIndexToModel(i);
}
int[] actualRow = new int[rowCount];
for(int i = 0; i<table.getRowCount(); i++){
actualRow[i] = table.convertRowIndexToModel(i);
}
Object[][] tempData = new Object[columnCount][rowCount];
for(int i = 0; i < columnCount; i++) {
for(int j = 0; j < rowCount; j++) {
tempData[i][j] = table.getValueAt(actualRow[j], actualColumn[i]);
}
}
return tempData;
};
尝试 3 是尝试 1 和尝试 2 的结合
最佳答案
RowSorterListener
中的代码指定用于正确返回索引(来自RowSorterListener
的事件)默认情况下,您永远不需要知道
JTable
View 中的顺序,所有这些事件都是模型事件
,添加
TableColumnModelListener
如果您想跟踪columnMoved
,所有以编程方式排序的事件都将绘制在JTable
的 View 中正确第一。尝试不对列重新排序,
Column NO. - 0 is sorted
Column NO. - 1 is sorted
Column NO. - 2 is sorted
Column NO. - 3 is sorted
Column NO. - 4 is sorted
... and so on
BUILD SUCCESSFUL (total time: 21 seconds)
.
- 第二。尝试对列进行重新排序(通过鼠标拖动)
.
Column NO. - 0 is sorted
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnSelectionChanged from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnSelectionChanged from ColumnModelListener
columnSelectionChanged from ColumnModelListener
columnSelectionChanged from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
Column NO. - 1 is sorted
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnSelectionChanged from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnSelectionChanged from ColumnModelListener
columnSelectionChanged from ColumnModelListener
columnSelectionChanged from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnSelectionChanged from ColumnModelListener
columnSelectionChanged from ColumnModelListener
columnSelectionChanged from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnSelectionChanged from ColumnModelListener
columnSelectionChanged from ColumnModelListener
columnSelectionChanged from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
Column NO. - 2 is sorted
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
columnMoved from ColumnModelListener
Column NO. - 3 is sorted
Column NO. - 4 is sorted
Column NO. - 0 is sorted
Column NO. - 1 is sorted
Column NO. - 2 is sorted
BUILD SUCCESSFUL (total time: 10 seconds)
第三。如果 Swing Timer 未初始化且所有事件均由用户手工制作,则尝试相同的正确输出
例如
.
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import javax.swing.*;
import javax.swing.RowSorter.SortKey;
import javax.swing.event.*;
import javax.swing.table.*;
public class SortTest1 {
private JFrame frame = new JFrame(getClass().getSimpleName());
private DefaultTableModel model = new DefaultTableModel(10, 5) {
private static final long serialVersionUID = 1L;
@Override
public Class<?> getColumnClass(int column) {
return getValueAt(0, column).getClass();
}
};
private JTable table = new JTable(model);
private TableRowSorter<?> sorter;
private static final Random rnd = new Random();
private Timer timer;
private int columnNo = 0;
public SortTest1() {
for (int row = model.getRowCount(); --row >= 0;) {
int i = 20 + row % 20;
model.setValueAt(row + " " + i, row, 0);
model.setValueAt(i + row, row, 1);
model.setValueAt(rnd.nextBoolean(), row, 2);
model.setValueAt(rnd.nextDouble(), row, 3);
model.setValueAt(row + " " + i * 1, row, 4);
}
table.setAutoCreateRowSorter(true);
sorter = (TableRowSorter<?>) table.getRowSorter();
sorter.setSortsOnUpdates(true);
sorter.addRowSorterListener(new RowSorterListener() {
@Override
public void sorterChanged(RowSorterEvent rse) {
if (rse.getType() == RowSorterEvent.Type.SORT_ORDER_CHANGED) {
List<SortKey> keys = rse.getSource().getSortKeys();
for (SortKey key : keys) {
System.out.println("Column NO. - " + key.getColumn() + " is sorted");
if (key.getColumn() == 0) {
break;
} else {
break;
}
}
}
}
});
frame.add(new JScrollPane(table));
table.setPreferredScrollableViewportSize(table.getPreferredSize());
table.getColumnModel().addColumnModelListener(new TableColumnModelListener() {
// just handle columnMarginChanged to re-paint headings
@Override
public void columnMarginChanged(ChangeEvent e) {
System.out.println("columnMarginChanged from ColumnModelListener");
}
@Override
public void columnAdded(TableColumnModelEvent e) {
System.out.println("columnAdded from ColumnModelListener");
}
@Override
public void columnRemoved(TableColumnModelEvent e) {
System.out.println("columnRemovedfrom ColumnModelListener");
}
@Override
public void columnMoved(TableColumnModelEvent e) {
System.out.println("columnMoved from ColumnModelListener");
}
@Override
public void columnSelectionChanged(ListSelectionEvent e) {
System.out.println("columnSelectionChanged from ColumnModelListener");
}
});
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
timer = new javax.swing.Timer(1000, updateCol());
timer.setRepeats(true);
timer.start();
}
private Action updateCol() {
return new AbstractAction("Sort JTable") {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent e) {
if (columnNo > 4) {
columnNo = 0;
sorter.setSortKeys(Arrays.asList(new RowSorter.SortKey(columnNo, SortOrder.ASCENDING)));
} else {
sorter.setSortKeys(Arrays.asList(new RowSorter.SortKey(columnNo, SortOrder.ASCENDING)));
columnNo++;
}
}
};
}
public static void main(String[] args) {
EventQueue.invokeLater(() -> {
new SortTest1();
});
}
}
关于java - 单击 JTable 标题时排序错误的列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34829921/