如何总是在结尾处对具有空值的jtable进行排序 [英] How to sort a jtable with null values always at the end
问题描述
我试图让我的JTable
在表末尾对空值进行排序.这类似于在SO( https://forums.oracle.com/thread/1351003 ),但这些线程的答案对我来说并不十分清楚. /p>
不过,使用这些答案确实取得了很大进步,并且我得到了下面发布的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;
}
}
}
我通过一个后续问题( 在我的原始帖子中,我正在创建自定义 I am trying to get my I did make a lot of progress using those answers, though, and I got as far as the SSCCE posted below. But I'm still trying to figure out how to get the null values (or, in the SSCCE I posted, the Anyone?
I solved the problem thanks to @MadProgrammer and @kleopatra through a follow-up question (Java Comparator always reading values as Strings) I had. The answer is to create a custom In my opinion, which is not worth much, this is not TOO hackish and does solve my problem, so I'm satisfied, even if others are not. Here is the complete code to my solution: In my original post, I was creating a custom 这篇关于如何总是在结尾处对具有空值的jtable进行排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!Comparator
,但是它无法访问getSortKeys()
.因此,我重写了TableRowSorter
中的getComparator()
方法,以便可以访问getSortKeys()
.可以.JTable
to sort null values at the end of the table. This is similar to a thread found at SO (How can i sort java JTable with an empty Row and force the Empty row always be last?) and OTN (https://forums.oracle.com/thread/1351003) but the answers in those threads aren't very clear to me.NullClassFiller
s) to always go to the bottom of the sort. I feel like if I could within the custom Comparator
somehow know which direction was being sorted (ascending or descending), I could get this easily to work. But Comparator
doesn't know the sort direction...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;
}
}
}
Comparator
that can determine which way the table is being sorted, then return the right value accordingly (if the sort is ASCENDING
then o1
needs to return 1
, and -1
visa versa, and o2
is exactly the opposite).import java.awt.Component;
import java.util.Comparator;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SortOrder;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;
public class Test {
public static void main(String args[]) {
JFrame frame = new JFrame();
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";
JTable table = new JTable();
table.setModel(new DefaultTableModel(data, new String[]{"One", "Two"}) {
@Override
public Class<?> getColumnClass(int column) {
return column == 0 ? Double.class : String.class;
}
@Override
public boolean isCellEditable(int row, int column) {
return false;
}
});
TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(table.getModel()) {
@Override
public Comparator<?> getComparator(final int column) {
Comparator c = new Comparator() {
@Override
public int compare(Object o1, Object o2) {
boolean ascending = getSortKeys().get(column).getSortOrder() == SortOrder.ASCENDING;
System.out.println(o1.getClass() + " - " + o2.getClass());
if (o1 instanceof NullClassFiller) {
if(ascending)
return 1;
else
return -1;
} else if (o2 instanceof NullClassFiller) {
if(ascending)
return -1;
else
return 1;
} else {
return ((Comparable<Object>) o1).compareTo(o2);
}
}
};
return c;
}
};
table.setRowSorter(sorter);
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 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;
}
}
}
Comparator
, but it had no access to getSortKeys()
. So, I overwrote the getComparator()
method in the TableRowSorter
so that I could access getSortKeys()
. It works.