让我们重温一下教程如何使用表格:排序和过滤。
除了对结果重新排序之外,表格排序器还可以指定将显示哪些行。这称为过滤。使用javax.swing.RowFilter对象TableRowSorter
实现过滤。实现了几个创建常见类型过滤器的工厂方法。RowFilter
要看的东西:
TableRowSorter
. - 我们知道我们需要这个。
- 哦,他们给了我们一个
RowFilter
文档链接。让我们在新的浏览器选项卡中打开它。
- 但首先最后一行“
RowFilter
实现了几个创建常见类型过滤器的工厂方法”。. 我们可能应该看看那些“常见的种类”是什么。
行过滤器 javadoc
- 静态方法 -
andFilter
, dateFilter
, notFilter
, numberFilter
, orFilter
, regexFilter
. 好的,我regexFilter
从教程中认出了。但其他那些,仅凭他们的名字,听起来不太有希望。也许我们应该实现我们自己的。让我们看看 javadoc 的其余部分
javax.swing.RowFilter<M,I>
类型参数:
M
- 模型的类型;例如PersonModel
I
- 标识符的类型;当使用TableRowSorter
这将是Integer
好的,从这里我们知道两件事。当我们创建我们的 customRowFilter
时,我们应该传递一个TableModel
类型作为第一个参数,并用 typeInteger
来表示行号。
RowFilter
用于从模型中过滤掉条目,以便它们不会显示在视图中。例如,与 aRowFilter
关联的 aJTable
可能只允许包含具有特定字符串的列的行。条目的含义取决于组件类型。例如,当过滤器与 关联时JTable
,条目对应于行;当与 a 关联时JTree
,条目对应于一个节点。
子类必须重写该include
方法以指示条目是否应显示在视图中。该Entry
参数可用于获取该条目中每一列的值
因此,基于这两个段落,我们知道RowFilter
用于过滤掉视图中不需要的行,如果我们创建自己的,我们将需要重写该include
方法以返回是否应显示行. 并且该include
方法还将有一个Entry
参数,在确定哪一行不返回 true 时,我们可以从中获取我们可能感兴趣的细节。这是javadoc给我们的基本示例(指南)
RowFilter<TableModel, Integer> filter = new RowFilter<TableModel, Integer>() {
@Override
public boolean include(RowFilter.Entry<? extends TableModel, ? extends Integer> entry) {
// do your logic here to return true or false.
}
};
很酷,但是这个RowFilter.Entry
类是什么,它可以为我们提供什么有趣的信息?让我们看一下javadoc。
我们可以看到的一件有趣的事情是getModel()
方法。从中我们可以得到我们的表格模型。所以让我们完成实现
private static final int CHECKBOX_COLUMN = 4;
...
RowFilter<TableModel, Integer> filter = new RowFilter<TableModel, Integer>() {
@Override
public boolean include(RowFilter.Entry<? extends TableModel, ? extends Integer> entry) {
int modelRow = entry.getIdentifier();
Boolean checked = (Boolean)entry.getModel().getValueAt(modelRow, CHECKBOX_COLUMN);
return checked;
}
};
也不多吧。现在剩下的就是将过滤器设置为排序器,正如您已经从 Oracle 教程中学到的那样,使用正则表达式过滤器。
这是一个填充演示代码。它没有实现ActionListener
按钮按下。我不想为你做一切。您应该有足够的信息来自己处理:-D 快乐学习!
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.RowFilter;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;
public class TableBooleanFilterDemo {
public TableBooleanFilterDemo() {
JTable table = getTable();
TableRowSorter<TableModel> rowSorter = new TableRowSorter<>(table.getModel());
RowFilter filter = getRowFilter();
rowSorter.setRowFilter(filter);
table.setRowSorter(rowSorter);
JFrame frame = new JFrame();
frame.add(new JScrollPane(table));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private static final int CHECKBOX_COLUMN = 4;
private RowFilter getRowFilter() {
RowFilter<TableModel, Integer> filter = new RowFilter<TableModel, Integer>() {
@Override
public boolean include(RowFilter.Entry<? extends TableModel, ? extends Integer> entry) {
int modelRow = entry.getIdentifier();
Boolean checked = (Boolean)entry.getModel().getValueAt(modelRow, CHECKBOX_COLUMN);
return checked;
}
};
return filter;
}
private JTable getTable() {
Object[][] data = {
{"Kathy", "Smith",
"Snowboarding", new Integer(5), new Boolean(false)},
{"John", "Doe",
"Rowing", new Integer(3), new Boolean(true)},
{"Sue", "Black",
"Knitting", new Integer(2), new Boolean(false)},
{"Jane", "White",
"Speed reading", new Integer(20), new Boolean(true)},
{"Joe", "Brown",
"Pool", new Integer(10), new Boolean(false)}
};
String[] columnNames = {"First Name",
"Last Name",
"Sport",
"# of Years",
"Vegetarian"};
return new JTable(new DefaultTableModel(data, columnNames) {
public Class getColumnClass(int c) {
return getValueAt(0, c).getClass();
}
});
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run() {
new TableBooleanFilterDemo();
}
});
}
}
老实说,我从来没有实现自己的RowFilter
,但以上是我在尝试学习新东西时几乎经历的过程。我花了更长的时间来写这个答案,然后学习如何去做。必须学会阅读文档,而不仅仅是教程。教程是一个很好的起点,但是一旦你遇到更复杂的问题,你就需要深入挖掘。与您想学习的任何新技术一样。