Я пытаюсь получить свой JTable
для сортировки нулевых значений в конце таблицы. Это похоже на поток, найденный в SO (How can i sort java JTable with an empty Row and force the Empty row always be last?) и OTN (https://forums.oracle.com/thread/1351003), но ответы в этих потоках мне не очень понятны.Как сортировать jtable с нулевыми значениями всегда в конце
Я сделал большой прогресс, используя эти ответы, хотя, и я дошел до SSCCE, размещенного ниже. Но я все еще пытаюсь выяснить, как получить нулевые значения (или, в опубликованном SSCCE, NullClassFiller
), чтобы всегда идти в нижней части сортировки. Я чувствую, что если бы я мог в пределах обычаев Comparator
как-то знал, какое направление сортируется (по восходящему или нисходящему), я мог бы легко это сделать. Но Comparator
не знает направления сортировки ...
Кто-нибудь?
import java.awt.Component;
import java.util.Comparator;
import javax.swing.DefaultRowSorter;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
public class Test {
public static void main(String args[]) {
JFrame frame = new JFrame();
JTable table = new JTable();
Object[][] data = new Object[8][3];
data[0][0] = 6.5d; data[0][1] = "Name1";
data[1][0] = new NullClassFiller(); data[1][1] = "Name2";
data[2][0] = 2.6d; data[2][1] = "Name3";
data[3][0] = 0d; data[3][1] = "Name4";
data[4][0] = new NullClassFiller(); data[4][1] = "Name5";
data[5][0] = -4d; data[5][1] = "Name6";
data[6][0] = 0d; data[6][1] = "Name7";
data[7][0] = -4.3d; data[7][1] = "Name8";
table.setModel(new DefaultTableModel(data, new String[]{"One", "Two"}));
table.setAutoCreateRowSorter(true);
DefaultRowSorter<?, ?> sorter = (DefaultRowSorter<?, ?>) table.getRowSorter();
sorter.setComparator(0, new CustomComparator());
table.getColumnModel().getColumn(0).setCellRenderer(new CustomRenderer());
JScrollPane pane = new JScrollPane(table);
frame.add(pane);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setSize(500, 500);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
static class CustomComparator implements Comparator<Object> {
@Override
public int compare(Object d1, Object d2) {
if (d1 instanceof NullClassFiller) {
return -1;
} else if (d2 instanceof NullClassFiller) {
return -1;
} else {
return ((Comparable<Object>) d1).compareTo(d2);
}
}
}
static class NullClassFiller {}
static class CustomRenderer extends DefaultTableCellRenderer {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
DefaultTableCellRenderer renderer = (DefaultTableCellRenderer) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if(value instanceof NullClassFiller)
renderer.setText("");
return renderer;
}
}
}
Возможный дубликат [Java Comparator всегда считывает значения как строки] (http://stackoverflow.com/questions/18680682/java-comparator-always-reading-values-as-stri ngs) – mKorbel
Хмм, не совсем понимаю вашу проблему с ответом/с в OTN - это просто невозможно сделать чистым способом, за исключением полной перезаписи DefaultRowSorter и TableRowSorter. Все остальные хаки рано или поздно будут ломаться. – kleopatra
@ kleopatra, проблема с (рабочими) решениями в OTN: их беспокоит только одна единственная пустая строка в конце, поэтому большинство из них - это хаки, которые включают нечто вроде public static final Object EMPTY_ROW = ""; , Это не работает для меня, потому что у меня много пустых строк. Вы говорите: «это просто невозможно сделать чистым способом, за исключением полной перезаписи DefaultRowSorter и TableRowSorter». что здорово, я готов укусить пулю и полностью переписать, я просто не знаю, как это сделать. Это моя попытка сделать именно это. – ryvantage