java筛选器JTable,带有不带分组字符的数字(千分位)
我正在尝试筛选JTable
中的行,其中包含带数字的列
到目前为止,过滤还在工作,但它过滤了包括数千个分隔符在内的数字。例如,如果一行中有一行的编号为25689,而我尝试筛选该行,则必须使用“25.689”。因此,似乎有一个格式化是在过滤之前执行的
我尝试设置自己的默认渲染器,显示的数字没有分隔符,但过滤是相同的
编辑
我已经添加了一个完整的示例来重新创建我的问题:
public class GroupingTest {
JFrame frame= null;
Container pane= null;
JTextField tf=null;
JXTable table=null;
public void searchTable() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
final String searchEx = "(?i)"
+ Pattern.quote(tf.getText());
final RowFilter<TableModel, Object> filter;
filter = RowFilter.regexFilter(searchEx);
table.setRowFilter(filter);
//packAll in edt
Utility.packTableView(table);
} catch (final Exception e) {
return;
}
}
});
}
public void createTable() {
frame = new JFrame();
pane=frame.getContentPane();
tf = new JTextField();
tf.setPreferredSize(new Dimension(200,25));
tf.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void removeUpdate(final DocumentEvent e) {
searchTable();
}
@Override
public void insertUpdate(final DocumentEvent e) {
searchTable();
}
@Override
public void changedUpdate(final DocumentEvent e) {
searchTable();
}
});
String[] columnHeaders = {"long","strings"};
DefaultTableModel $model = new DefaultTableModel(columnHeaders, 0) {
@Override
public Class<?> getColumnClass(final int $col) {
if($col == 0) {
return Long.class;
} else if($col == 1){
return String.class;
} else {
return Object.class;
}
}
};
table = new JXTable($model);
table.setDefaultRenderer(Long.class, new DefaultTableCellRenderer() {
@Override
public java.awt.Component getTableCellRendererComponent(final JTable $table,
final Object $value, final boolean $isSelected, final boolean $hasFocus, final int $row,
final int $column) {
super.getTableCellRendererComponent($table, $value, $isSelected, $hasFocus, $row, $column);
if ($value instanceof Long) {
this.setHorizontalAlignment(SwingConstants.RIGHT);
}
return this;
}
});
Object[] line1 = {new Long(23345),"asdf"};
$model.addRow(line1);
Object[] line2 = {new Long(3),"dfw"};
$model.addRow(line2);
pane.add(tf,BorderLayout.NORTH);
pane.add(new JScrollPane(table),BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setPreferredSize(new Dimension(300,200));
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
GroupingTest gt = new GroupingTest();
gt.createTable();
}
}
# 1 楼答案
当值的格式干扰了分类器和过滤器的预期功能时,就应该检查表模型中的getColumnClass(int columnIndex)是否正在检索适当的类(在本例中为
Double
)默认情况下,这种方法的
AbstractTableModel
实现返回Object.class
,它是使用toString()
方法呈现的(这就是为什么您会看到千位分隔符),并且可能也会根据字符串表示进行过滤。AbstractTableModel
的子类(如DefaultTableModel
)继承此实现,因此应重写此方法。例如,假设您的表模型是DefaultTableModel
,第一列是Double
:有关更多详细信息,请参见How to Use Tables教程的Sorting and Filtering部分
更新
考虑到你的新MVCE,现在很清楚你想要实现什么。我开始说,我错误地假设您的表模型持有的是
Double
,而不是Long
,这对重写getColumnClass()
方法没有影响(无论如何都应该这样做),但对最终的解决方案会有轻微的影响现在,为了明确说明需求,您需要筛选该列:
为了实现这个目标,我将使用一个自定义的
RowFilter
,而不是像您在示例中那样使用正则表达式过滤器。这是为了控制用户键入的字符串,并检查上面列出的三个条件。我已经设法修改了你的searchTable()
以满足要求。注意:我将查询的字符串作为参数包含在这个方法中,以使tf
文本字段不在实现中。请参阅下面的代码:流量大致如下所示:
如果查询长度为0,则让筛选器为
null
。这意味着该表不会被过滤,所有租金都将包括在内如果不是(1),则准备一个新的过滤器,该过滤器将迭代整行,询问条目的字符串表示形式或条目的字符串值是否包含查询的字符串。虽然它们看起来可能是相同的,但它们不是,因为Entry#getStringValue(int index)可能(实际上)检索到与String#valueOf(entry#getValue(int index))不同的值。在这种情况下,第一个检索包含分组分隔符的Long(或格式化,如果您愿意),而第二个检索完全没有格式化的Long(这意味着没有分组分隔符)
在这两种情况下,都将筛选器应用于表
我希望这个想法足够清楚。如果要筛选
Double
,则必须稍微调整它,因为String.valueOf(double)
包含十进制(非分组)分隔符,您可能希望在检查它是否包含查询的字符串之前删除它